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,
node_id: String,
modifications: Vec<AttrModification>,
can_gc: CanGc,
) {
let Some(document) = documents.find_document(pipeline) else {
return warn!("document for pipeline id {} is not found", &pipeline);
@ -421,6 +422,7 @@ pub fn handle_modify_attribute(
let _ = elem.SetAttribute(
DOMString::from(modification.attribute_name),
DOMString::from(string),
can_gc,
);
},
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::node::Node;
use crate::dom::virtualmethods::vtable_for;
use crate::script_runtime::CanGc;
use crate::script_thread::ScriptThread;
// https://dom.spec.whatwg.org/#interface-attr
@ -60,7 +61,7 @@ impl Attr {
owner: MutNullableDom::new(owner),
}
}
#[allow(clippy::too_many_arguments)]
pub fn new(
document: &Document,
local_name: LocalName,
@ -69,12 +70,14 @@ impl Attr {
namespace: Namespace,
prefix: Option<Prefix>,
owner: Option<&Element>,
can_gc: CanGc,
) -> DomRoot<Attr> {
Node::reflect_node(
Box::new(Attr::new_inherited(
document, local_name, value, name, namespace, prefix, owner,
)),
document,
can_gc,
)
}

View file

@ -66,6 +66,14 @@ DOMInterfaces = {
'canGc': ['GetTransform','GetImageData', 'CreateImageData', 'CreateImageData_', 'SetFont', 'FillText', 'MeasureText', 'SetStrokeStyle', 'SetFillStyle', 'SetShadowColor'],
},
'CharacterData': {
'canGc': ['Before', 'After', 'ReplaceWith']
},
'CSSStyleDeclaration': {
'canGc': ['RemoveProperty', 'SetCssText']
},
'CanvasGradient': {
'canGc': ['AddColorStop'],
},
@ -76,7 +84,7 @@ DOMInterfaces = {
},
'DOMImplementation': {
'canGc': ['CreateDocument', 'CreateHTMLDocument'],
'canGc': ['CreateDocument', 'CreateHTMLDocument', 'CreateDocumentType'],
},
'DOMMatrix': {
@ -104,15 +112,31 @@ DOMInterfaces = {
},
'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': {
'inRealms': ['PromiseAttribute'],
},
'DocumentFragment': {
'canGc': ['Prepend', 'Append', 'ReplaceChildren']
},
'DocumentType': {
'canGc': ['Before', 'After', 'ReplaceWith']
},
'DOMStringMap': {
'canGc': ['NamedSetter']
},
"DOMTokenList": {
'canGc': ['SetValue', 'Add', 'Remove', 'Toggle', 'Replace']
},
'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': {
@ -184,31 +208,47 @@ DOMInterfaces = {
},
'HTMLButtonElement': {
'canGc': ['CheckValidity', 'ReportValidity'],
'canGc': ['CheckValidity', 'ReportValidity','SetBackground'],
},
'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': {
'canGc': ['CheckValidity', 'ReportValidity'],
},
'HTMLDialogElement': {
'canGc': ['Show'],
},
'HTMLFormElement': {
'canGc': ['CheckValidity', 'RequestSubmit', 'ReportValidity', 'Submit'],
'canGc': ['CheckValidity', 'RequestSubmit', 'ReportValidity', 'Submit', 'Reset', 'SetRel'],
},
'HTMLImageElement': {
'canGc': ['Width', 'Height', 'Decode'],
'canGc': ['RequestSubmit', 'ReportValidity', 'Reset','SetRel', 'Width', 'Height', 'Decode', 'SetCrossOrigin', 'SetWidth', 'SetHeight', 'SetReferrerPolicy'],
},
'HTMLFontElement': {
'canGc': ['SetSize']
},
'HTMLInputElement': {
'canGc': ['CheckValidity', 'ReportValidity', 'SelectFiles'],
'canGc': ['ReportValidity', 'SetValue', 'SetValueAsNumber', 'SetValueAsDate', 'StepUp', 'StepDown', 'CheckValidity', 'ReportValidity', 'SelectFiles'],
},
"HTMLAreaElement": {
"canGc": ["SetRel"]
},
"HTMLBodyElement": {
"canGc": ["SetBackground"]
},
'HTMLMediaElement': {
'canGc': ['Load', 'Pause', 'Play', 'SetSrcObject'],
'canGc': ['Load', 'Pause', 'Play', 'SetSrcObject', 'SetCrossOrigin'],
'inRealms': ['Play'],
},
@ -217,7 +257,11 @@ DOMInterfaces = {
},
'HTMLOutputElement': {
'canGc': ['CheckValidity', 'ReportValidity'],
'canGc': ['ReportValidity', 'SetDefaultValue', 'SetValue', 'CheckValidity'],
},
'HTMLMeterElement': {
'canGc': ['SetValue', 'SetMin', 'SetMax', 'SetLow', 'SetHigh', 'SetOptimum', 'CheckValidity', 'ReportValidity']
},
'HTMLCanvasElement': {
@ -225,15 +269,55 @@ DOMInterfaces = {
},
'HTMLSelectElement': {
'canGc': ['CheckValidity', 'ReportValidity'],
'canGc': ['ReportValidity', 'SetLength', 'IndexedSetter', 'CheckValidity'],
},
'HTMLTemplateElement': {
'canGc': ['Content'],
},
'HTMLTitleElement': {
'canGc': ['SetText']
},
'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': {
@ -275,7 +359,7 @@ DOMInterfaces = {
},
'Node': {
'canGc': ['CloneNode'],
'canGc': ['CloneNode', 'SetTextContent'],
},
'OfflineAudioContext': {
@ -313,7 +397,7 @@ DOMInterfaces = {
},
'Range': {
'canGc': ['CloneContents', 'CloneRange', 'CreateContextualFragment', 'ExtractContents', 'SurroundContents'],
'canGc': ['CloneContents', 'CloneRange', 'CreateContextualFragment', 'ExtractContents', 'SurroundContents', 'InsertNode'],
'weakReferenceable': True,
},
@ -348,6 +432,10 @@ DOMInterfaces = {
'canGc': ['Encrypt', 'Decrypt', 'GenerateKey', 'ImportKey', 'ExportKey'],
},
'SVGElement': {
'canGc': ['SetAutofocus']
},
#FIXME(jdm): This should be 'register': False, but then we don't generate enum types
'TestBinding': {
'inRealms': ['PromiseAttribute', 'PromiseNativeHandler'],
@ -359,6 +447,10 @@ DOMInterfaces = {
'canGc': ['AddModule'],
},
'Text': {
'canGc': ['SplitText']
},
'URL': {
'weakReferenceable': True,
'canGc': ['Parse', 'SearchParams'],

View file

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

View file

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

View file

@ -9,6 +9,7 @@ use crate::dom::bindings::str::DOMString;
use crate::dom::document::Document;
use crate::dom::node::Node;
use crate::dom::text::Text;
use crate::script_runtime::CanGc;
#[dom_struct]
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(
Box::new(CDATASection::new_inherited(text, 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::text::Text;
use crate::dom::virtualmethods::vtable_for;
use crate::script_runtime::CanGc;
// https://dom.spec.whatwg.org/#characterdata
#[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() {
NodeTypeId::CharacterData(CharacterDataTypeId::Comment) => {
DomRoot::upcast(Comment::new(data, document, None))
DomRoot::upcast(Comment::new(data, document, None, can_gc))
},
NodeTypeId::CharacterData(CharacterDataTypeId::ProcessingInstruction) => {
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)) => {
DomRoot::upcast(CDATASection::new(data, document))
DomRoot::upcast(CDATASection::new(data, document, can_gc))
},
NodeTypeId::CharacterData(CharacterDataTypeId::Text(TextTypeId::Text)) => {
DomRoot::upcast(Text::new(data, document))
DomRoot::upcast(Text::new(data, document, can_gc))
},
_ => unreachable!(),
}
@ -243,18 +254,18 @@ impl CharacterDataMethods for CharacterData {
}
// https://dom.spec.whatwg.org/#dom-childnode-before
fn Before(&self, nodes: Vec<NodeOrString>) -> ErrorResult {
self.upcast::<Node>().before(nodes)
fn Before(&self, nodes: Vec<NodeOrString>, can_gc: CanGc) -> ErrorResult {
self.upcast::<Node>().before(nodes, can_gc)
}
// https://dom.spec.whatwg.org/#dom-childnode-after
fn After(&self, nodes: Vec<NodeOrString>) -> ErrorResult {
self.upcast::<Node>().after(nodes)
fn After(&self, nodes: Vec<NodeOrString>, can_gc: CanGc) -> ErrorResult {
self.upcast::<Node>().after(nodes, can_gc)
}
// https://dom.spec.whatwg.org/#dom-childnode-replacewith
fn ReplaceWith(&self, nodes: Vec<NodeOrString>) -> ErrorResult {
self.upcast::<Node>().replace_with(nodes)
fn ReplaceWith(&self, nodes: Vec<NodeOrString>, can_gc: CanGc) -> ErrorResult {
self.upcast::<Node>().replace_with(nodes, can_gc)
}
// https://dom.spec.whatwg.org/#dom-childnode-remove

View file

@ -33,11 +33,13 @@ impl Comment {
text: DOMString,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<Comment> {
Node::reflect_node_with_proto(
Box::new(Comment::new_inherited(text, document)),
document,
proto,
can_gc,
)
}
}
@ -47,10 +49,10 @@ impl CommentMethods for Comment {
fn Constructor(
window: &Window,
proto: Option<HandleObject>,
_can_gc: CanGc,
can_gc: CanGc,
data: DOMString,
) -> Fallible<DomRoot<Comment>> {
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(
($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)
});
($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)
})
);
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 {
@ -145,6 +145,7 @@ fn create_html_element(
prefix.clone(),
document,
proto,
can_gc,
));
result.set_custom_element_state(CustomElementState::Undefined);
ScriptThread::enqueue_upgrade_reaction(&result, definition);
@ -173,7 +174,7 @@ fn create_html_element(
// Step 6.1.2
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
@ -231,11 +232,11 @@ pub fn create_native_html_element(
macro_rules! make(
($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)
});
($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)
})
);
@ -406,6 +407,6 @@ pub fn create_element(
match name.ns {
ns!(html) => create_html_element(name, prefix, is, document, creator, mode, proto, can_gc),
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 {
// Mutate the declaration block associated to this style owner, and
// 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
F: FnOnce(&mut PropertyDeclarationBlock, &mut bool) -> R,
{
@ -103,6 +103,7 @@ impl CSSStyleOwner {
el.set_attribute(
&local_name!("style"),
AttrValue::Declaration(serialization, pdb),
can_gc,
);
}
} else {
@ -287,61 +288,64 @@ impl CSSStyleDeclaration {
return Ok(());
}
self.owner.mutate_associated_block(|pdb, changed| {
if value.is_empty() {
// Step 3
*changed = remove_property(pdb, &id);
return Ok(());
}
// Step 4
let importance = match &*priority {
"" => Importance::Normal,
p if p.eq_ignore_ascii_case("important") => Importance::Important,
_ => {
*changed = false;
self.owner.mutate_associated_block(
|pdb, changed| {
if value.is_empty() {
// Step 3
*changed = remove_property(pdb, &id);
return Ok(());
},
};
}
// Step 5
let window = self.owner.window();
let quirks_mode = window.Document().quirks_mode();
let mut declarations = SourcePropertyDeclaration::default();
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 4
let importance = match &*priority {
"" => Importance::Normal,
p if p.eq_ignore_ascii_case("important") => Importance::Important,
_ => {
*changed = false;
return Ok(());
},
};
// Step 6
match result {
Ok(()) => {},
Err(_) => {
*changed = false;
// Step 5
let window = self.owner.window();
let quirks_mode = window.Document().quirks_mode();
let mut declarations = SourcePropertyDeclaration::default();
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(());
},
}
}
let mut updates = Default::default();
*changed = pdb.prepare_for_update(&declarations, importance, &mut updates);
// Step 7
// Step 8
pdb.update(declarations.drain(), importance, &mut updates);
if !*changed {
return Ok(());
}
// Step 7
// Step 8
pdb.update(declarations.drain(), importance, &mut updates);
Ok(())
})
Ok(())
},
CanGc::note(),
)
}
}
@ -435,7 +439,7 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
}
// 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
if self.readonly {
return Err(Error::NoModificationAllowed);
@ -447,10 +451,13 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
};
let mut string = String::new();
self.owner.mutate_associated_block(|pdb, changed| {
pdb.property_value_to_css(&id, &mut string).unwrap();
*changed = remove_property(pdb, &id);
});
self.owner.mutate_associated_block(
|pdb, changed| {
pdb.property_value_to_css(&id, &mut string).unwrap();
*changed = remove_property(pdb, &id);
},
can_gc,
);
// Step 6
Ok(DOMString::from(string))
@ -498,7 +505,7 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
}
// 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();
// Step 1
@ -507,16 +514,19 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
}
let quirks_mode = window.Document().quirks_mode();
self.owner.mutate_associated_block(|pdb, _changed| {
// Step 3
*pdb = parse_style_attribute(
&value,
&UrlExtraData(self.owner.base_url().get_arc()),
window.css_error_reporter(),
quirks_mode,
CssRuleType::Style,
);
});
self.owner.mutate_associated_block(
|pdb, _changed| {
// Step 3
*pdb = parse_style_attribute(
&value,
&UrlExtraData(self.owner.base_url().get_arc()),
window.css_error_reporter(),
quirks_mode,
CssRuleType::Style,
);
},
can_gc,
);
Ok(())
}

View file

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

View file

@ -40,18 +40,20 @@ impl DocumentFragment {
}
}
pub fn new(document: &Document) -> DomRoot<DocumentFragment> {
Self::new_with_proto(document, None)
pub fn new(document: &Document, can_gc: CanGc) -> DomRoot<DocumentFragment> {
Self::new_with_proto(document, None, can_gc)
}
fn new_with_proto(
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<DocumentFragment> {
Node::reflect_node_with_proto(
Box::new(DocumentFragment::new_inherited(document)),
document,
proto,
can_gc,
)
}
@ -65,11 +67,11 @@ impl DocumentFragmentMethods for DocumentFragment {
fn Constructor(
window: &Window,
proto: Option<HandleObject>,
_can_gc: CanGc,
can_gc: CanGc,
) -> Fallible<DomRoot<DocumentFragment>> {
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
@ -106,18 +108,18 @@ impl DocumentFragmentMethods for DocumentFragment {
}
// https://dom.spec.whatwg.org/#dom-parentnode-prepend
fn Prepend(&self, nodes: Vec<NodeOrString>) -> ErrorResult {
self.upcast::<Node>().prepend(nodes)
fn Prepend(&self, nodes: Vec<NodeOrString>, can_gc: CanGc) -> ErrorResult {
self.upcast::<Node>().prepend(nodes, can_gc)
}
// https://dom.spec.whatwg.org/#dom-parentnode-append
fn Append(&self, nodes: Vec<NodeOrString>) -> ErrorResult {
self.upcast::<Node>().append(nodes)
fn Append(&self, nodes: Vec<NodeOrString>, can_gc: CanGc) -> ErrorResult {
self.upcast::<Node>().append(nodes, can_gc)
}
// https://dom.spec.whatwg.org/#dom-parentnode-replacechildren
fn ReplaceChildren(&self, nodes: Vec<NodeOrString>) -> ErrorResult {
self.upcast::<Node>().replace_children(nodes)
fn ReplaceChildren(&self, nodes: Vec<NodeOrString>, can_gc: CanGc) -> ErrorResult {
self.upcast::<Node>().replace_children(nodes, can_gc)
}
// 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::document::Document;
use crate::dom::node::Node;
use crate::script_runtime::CanGc;
// https://dom.spec.whatwg.org/#documenttype
/// The `DOCTYPE` tag.
@ -43,12 +44,14 @@ impl DocumentType {
public_id: Option<DOMString>,
system_id: Option<DOMString>,
document: &Document,
can_gc: CanGc,
) -> DomRoot<DocumentType> {
Node::reflect_node(
Box::new(DocumentType::new_inherited(
name, public_id, system_id, document,
)),
document,
can_gc,
)
}
@ -85,18 +88,18 @@ impl DocumentTypeMethods for DocumentType {
}
// https://dom.spec.whatwg.org/#dom-childnode-before
fn Before(&self, nodes: Vec<NodeOrString>) -> ErrorResult {
self.upcast::<Node>().before(nodes)
fn Before(&self, nodes: Vec<NodeOrString>, can_gc: CanGc) -> ErrorResult {
self.upcast::<Node>().before(nodes, can_gc)
}
// https://dom.spec.whatwg.org/#dom-childnode-after
fn After(&self, nodes: Vec<NodeOrString>) -> ErrorResult {
self.upcast::<Node>().after(nodes)
fn After(&self, nodes: Vec<NodeOrString>, can_gc: CanGc) -> ErrorResult {
self.upcast::<Node>().after(nodes, can_gc)
}
// https://dom.spec.whatwg.org/#dom-childnode-replacewith
fn ReplaceWith(&self, nodes: Vec<NodeOrString>) -> ErrorResult {
self.upcast::<Node>().replace_with(nodes)
fn ReplaceWith(&self, nodes: Vec<NodeOrString>, can_gc: CanGc) -> ErrorResult {
self.upcast::<Node>().replace_with(nodes, can_gc)
}
// https://dom.spec.whatwg.org/#dom-childnode-remove

View file

@ -59,6 +59,7 @@ impl DOMImplementationMethods for DOMImplementation {
qualified_name: DOMString,
pubid: DOMString,
sysid: DOMString,
can_gc: CanGc,
) -> Fallible<DomRoot<DocumentType>> {
validate_qualified_name(&qualified_name)?;
Ok(DocumentType::new(
@ -66,6 +67,7 @@ impl DOMImplementationMethods for DOMImplementation {
Some(pubid),
Some(sysid),
&self.document,
can_gc,
))
}
@ -165,7 +167,7 @@ impl DOMImplementationMethods for DOMImplementation {
{
// Step 3.
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();
}
@ -177,6 +179,7 @@ impl DOMImplementationMethods for DOMImplementation {
None,
&doc,
None,
can_gc,
));
doc_node.AppendChild(&doc_html).expect("Appending failed");
@ -187,6 +190,7 @@ impl DOMImplementationMethods for DOMImplementation {
None,
&doc,
None,
can_gc,
));
doc_html.AppendChild(&doc_head).unwrap();
@ -198,17 +202,18 @@ impl DOMImplementationMethods for DOMImplementation {
None,
&doc,
None,
can_gc,
));
doc_head.AppendChild(&doc_title).unwrap();
// 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();
}
}
// 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();
}

View file

@ -11,6 +11,7 @@ use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::DOMString;
use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::window_from_node;
use crate::script_runtime::CanGc;
#[dom_struct]
pub struct DOMStringMap {
@ -40,8 +41,8 @@ impl DOMStringMapMethods for DOMStringMap {
}
// https://html.spec.whatwg.org/multipage/#dom-domstringmap-setitem
fn NamedSetter(&self, name: DOMString, value: DOMString) -> ErrorResult {
self.element.set_custom_attr(name, value)
fn NamedSetter(&self, name: DOMString, value: DOMString, can_gc: CanGc) -> ErrorResult {
self.element.set_custom_attr(name, value, can_gc)
}
// 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::element::Element;
use crate::dom::node::window_from_node;
use crate::script_runtime::CanGc;
#[dom_struct]
pub struct DOMTokenList {
@ -69,14 +70,14 @@ impl DOMTokenList {
}
/// <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
if !self.element.has_attribute(&self.local_name) && atoms.is_empty() {
return;
}
// step 2
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>
@ -130,7 +131,7 @@ impl DOMTokenListMethods for DOMTokenList {
}
/// <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);
for token in &tokens {
let token = self.check_token_exceptions(token)?;
@ -138,12 +139,12 @@ impl DOMTokenListMethods for DOMTokenList {
atoms.push(token);
}
}
self.perform_update_steps(atoms);
self.perform_update_steps(atoms, can_gc);
Ok(())
}
/// <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);
for token in &tokens {
let token = self.check_token_exceptions(token)?;
@ -152,12 +153,12 @@ impl DOMTokenListMethods for DOMTokenList {
.position(|atom| *atom == token)
.map(|index| atoms.remove(index));
}
self.perform_update_steps(atoms);
self.perform_update_steps(atoms, can_gc);
Ok(())
}
/// <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 token = self.check_token_exceptions(&token)?;
match atoms.iter().position(|atom| *atom == token) {
@ -165,7 +166,7 @@ impl DOMTokenListMethods for DOMTokenList {
Some(true) => Ok(true),
_ => {
atoms.remove(index);
self.perform_update_steps(atoms);
self.perform_update_steps(atoms, can_gc);
Ok(false)
},
},
@ -173,7 +174,7 @@ impl DOMTokenListMethods for DOMTokenList {
Some(false) => Ok(false),
_ => {
atoms.push(token);
self.perform_update_steps(atoms);
self.perform_update_steps(atoms, can_gc);
Ok(true)
},
},
@ -186,13 +187,13 @@ impl DOMTokenListMethods for DOMTokenList {
}
/// <https://dom.spec.whatwg.org/#dom-domtokenlist-value>
fn SetValue(&self, value: DOMString) {
fn SetValue(&self, value: DOMString, can_gc: CanGc) {
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>
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() {
// Step 1.
return Err(Error::Syntax);
@ -231,7 +232,7 @@ impl DOMTokenListMethods for DOMTokenList {
}
// Step 5.
self.perform_update_steps(atoms);
self.perform_update_steps(atoms, can_gc);
result = true;
}
Ok(result)

View file

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

View file

@ -67,6 +67,7 @@ impl HTMLAnchorElement {
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLAnchorElement> {
Node::reflect_node_with_proto(
Box::new(HTMLAnchorElement::new_inherited(
@ -74,6 +75,7 @@ impl HTMLAnchorElement {
)),
document,
proto,
can_gc,
)
}
@ -115,9 +117,9 @@ impl HTMLAnchorElement {
}
// 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>()
.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
fn SetText(&self, value: DOMString) {
self.upcast::<Node>().SetTextContent(Some(value))
fn SetText(&self, value: DOMString, can_gc: CanGc) {
self.upcast::<Node>().SetTextContent(Some(value), can_gc)
}
// https://html.spec.whatwg.org/multipage/#dom-a-rel
make_getter!(Rel, "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>()
.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
@ -239,7 +241,7 @@ impl HTMLAnchorElementMethods for HTMLAnchorElement {
}
// https://html.spec.whatwg.org/multipage/#dom-hyperlink-hash
fn SetHash(&self, value: USVString) {
fn SetHash(&self, value: USVString, can_gc: CanGc) {
// Step 1.
self.reinitialize_url();
@ -255,7 +257,7 @@ impl HTMLAnchorElementMethods for HTMLAnchorElement {
},
};
// Step 6.
self.update_href(url);
self.update_href(url, can_gc);
}
// 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
fn SetHost(&self, value: USVString) {
fn SetHost(&self, value: USVString, can_gc: CanGc) {
// Step 1.
self.reinitialize_url();
@ -294,7 +296,7 @@ impl HTMLAnchorElementMethods for HTMLAnchorElement {
},
};
// Step 5.
self.update_href(url);
self.update_href(url, can_gc);
}
// 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
fn SetHostname(&self, value: USVString) {
fn SetHostname(&self, value: USVString, can_gc: CanGc) {
// Step 1.
self.reinitialize_url();
@ -329,7 +331,7 @@ impl HTMLAnchorElementMethods for HTMLAnchorElement {
},
};
// Step 5.
self.update_href(url);
self.update_href(url, can_gc);
}
// 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
fn SetHref(&self, value: USVString) {
self.upcast::<Element>()
.set_string_attribute(&local_name!("href"), DOMString::from_string(value.0));
fn SetHref(&self, value: USVString, can_gc: CanGc) {
self.upcast::<Element>().set_string_attribute(
&local_name!("href"),
DOMString::from_string(value.0),
can_gc,
);
self.set_url();
}
@ -392,7 +397,7 @@ impl HTMLAnchorElementMethods for HTMLAnchorElement {
}
// https://html.spec.whatwg.org/multipage/#dom-hyperlink-password
fn SetPassword(&self, value: USVString) {
fn SetPassword(&self, value: USVString, can_gc: CanGc) {
// Step 1.
self.reinitialize_url();
@ -408,7 +413,7 @@ impl HTMLAnchorElementMethods for HTMLAnchorElement {
},
};
// Step 5.
self.update_href(url);
self.update_href(url, can_gc);
}
// 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
fn SetPathname(&self, value: USVString) {
fn SetPathname(&self, value: USVString, can_gc: CanGc) {
// Step 1.
self.reinitialize_url();
@ -441,7 +446,7 @@ impl HTMLAnchorElementMethods for HTMLAnchorElement {
},
};
// Step 6.
self.update_href(url);
self.update_href(url, can_gc);
}
// 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
fn SetPort(&self, value: USVString) {
fn SetPort(&self, value: USVString, can_gc: CanGc) {
// Step 1.
self.reinitialize_url();
@ -477,7 +482,7 @@ impl HTMLAnchorElementMethods for HTMLAnchorElement {
},
};
// Step 5.
self.update_href(url);
self.update_href(url, can_gc);
}
// 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
fn SetProtocol(&self, value: USVString) {
fn SetProtocol(&self, value: USVString, can_gc: CanGc) {
// Step 1.
self.reinitialize_url();
@ -508,7 +513,7 @@ impl HTMLAnchorElementMethods for HTMLAnchorElement {
},
};
// Step 4.
self.update_href(url);
self.update_href(url, can_gc);
}
// 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
fn SetSearch(&self, value: USVString) {
fn SetSearch(&self, value: USVString, can_gc: CanGc) {
// Step 1.
self.reinitialize_url();
@ -542,7 +547,7 @@ impl HTMLAnchorElementMethods for HTMLAnchorElement {
},
};
// Step 6.
self.update_href(url);
self.update_href(url, can_gc);
}
// 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
fn SetUsername(&self, value: USVString) {
fn SetUsername(&self, value: USVString, can_gc: CanGc) {
// Step 1.
self.reinitialize_url();
@ -575,7 +580,7 @@ impl HTMLAnchorElementMethods for HTMLAnchorElement {
},
};
// Step 5.
self.update_href(url);
self.update_href(url, can_gc);
}
}

View file

@ -264,11 +264,13 @@ impl HTMLAreaElement {
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLAreaElement> {
Node::reflect_node_with_proto(
Box::new(HTMLAreaElement::new_inherited(local_name, prefix, document)),
document,
proto,
can_gc,
)
}
@ -341,9 +343,9 @@ impl HTMLAreaElementMethods for HTMLAreaElement {
make_getter!(Rel, "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>()
.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

View file

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

View file

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

View file

@ -24,6 +24,7 @@ use crate::dom::eventtarget::EventTarget;
use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::{document_from_node, window_from_node, BindContext, Node};
use crate::dom::virtualmethods::VirtualMethods;
use crate::script_runtime::CanGc;
/// How long we should wait before performing the initial reflow after `<body>` is parsed.
const INITIAL_REFLOW_DELAY: Duration = Duration::from_millis(200);
@ -50,11 +51,13 @@ impl HTMLBodyElement {
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLBodyElement> {
Node::reflect_node_with_proto(
Box::new(HTMLBodyElement::new_inherited(local_name, prefix, document)),
document,
proto,
can_gc,
)
}
@ -87,13 +90,13 @@ impl HTMLBodyElementMethods for HTMLBodyElement {
make_getter!(Background, "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(
&document_from_node(self).base_url().get_arc(),
input.into(),
);
self.upcast::<Element>()
.set_attribute(&local_name!("background"), value);
.set_attribute(&local_name!("background"), value, can_gc);
}
// 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::htmlelement::HTMLElement;
use crate::dom::node::Node;
use crate::script_runtime::CanGc;
#[dom_struct]
pub struct HTMLBRElement {
@ -33,11 +34,13 @@ impl HTMLBRElement {
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLBRElement> {
Node::reflect_node_with_proto(
Box::new(HTMLBRElement::new_inherited(local_name, prefix, document)),
document,
proto,
can_gc,
)
}
}

View file

@ -75,6 +75,7 @@ impl HTMLButtonElement {
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLButtonElement> {
Node::reflect_node_with_proto(
Box::new(HTMLButtonElement::new_inherited(
@ -82,6 +83,7 @@ impl HTMLButtonElement {
)),
document,
proto,
can_gc,
)
}
@ -360,7 +362,7 @@ impl Activatable for HTMLButtonElement {
ButtonType::Reset => {
// TODO: is document owner fully active?
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>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLCanvasElement> {
Node::reflect_node_with_proto(
Box::new(HTMLCanvasElement::new_inherited(
@ -93,6 +94,7 @@ impl HTMLCanvasElement {
)),
document,
proto,
can_gc,
)
}

View file

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

View file

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

View file

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

View file

@ -16,6 +16,7 @@ use crate::dom::element::Element;
use crate::dom::eventtarget::EventTarget;
use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::{window_from_node, Node};
use crate::script_runtime::CanGc;
#[dom_struct]
pub struct HTMLDialogElement {
@ -41,6 +42,7 @@ impl HTMLDialogElement {
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLDialogElement> {
Node::reflect_node_with_proto(
Box::new(HTMLDialogElement::new_inherited(
@ -48,6 +50,7 @@ impl HTMLDialogElement {
)),
document,
proto,
can_gc,
)
}
}
@ -71,7 +74,7 @@ impl HTMLDialogElementMethods for HTMLDialogElement {
}
/// <https://html.spec.whatwg.org/multipage/#dom-dialog-show>
fn Show(&self) {
fn Show(&self, can_gc: CanGc) {
let element = self.upcast::<Element>();
// 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.
// 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.

View file

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

View file

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

View file

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

View file

@ -95,11 +95,13 @@ impl HTMLElement {
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLElement> {
Node::reflect_node_with_proto(
Box::new(HTMLElement::new_inherited(local_name, prefix, document)),
document,
proto,
can_gc,
)
}
@ -481,10 +483,10 @@ impl HTMLElementMethods for HTMLElement {
}
/// <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
// 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.
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>
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.
let Some(parent) = self.upcast::<Node>().GetParentNode() else {
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
// 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
// string and node document is this's node document to fragment.
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())?;
}
@ -548,13 +550,14 @@ impl HTMLElementMethods for HTMLElement {
}
// 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(
&html5ever::local_name!("translate"),
match yesno {
true => DOMString::from("yes"),
false => DOMString::from("no"),
},
can_gc,
);
}
@ -625,14 +628,19 @@ impl HTMLElementMethods for HTMLElement {
}
// https://html.spec.whatwg.org/multipage/#dom-fe-autofocus
fn SetAutofocus(&self, autofocus: bool) {
fn SetAutofocus(&self, autofocus: bool, can_gc: CanGc) {
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) {
let text = Text::new(DOMString::from(text), document);
fn append_text_node_to_fragment(
document: &Document,
fragment: &DocumentFragment,
text: String,
can_gc: CanGc,
) {
let text = Text::new(DOMString::from(text), document, can_gc);
fragment
.upcast::<Node>()
.AppendChild(text.upcast())
@ -695,7 +703,7 @@ fn to_camel_case(name: &str) -> Option<DOMString> {
}
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
.chars()
.skip_while(|&ch| ch != '\u{2d}')
@ -705,7 +713,7 @@ impl HTMLElement {
return Err(Error::Syntax);
}
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> {
@ -926,10 +934,10 @@ impl HTMLElement {
}
/// <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.
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
// of input.
@ -951,11 +959,11 @@ impl HTMLElement {
}
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();
}
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();
},
_ => {
@ -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
// document is document to fragment.
if !text.is_empty() {
append_text_node_to_fragment(&document, &fragment, text);
append_text_node_to_fragment(&document, &fragment, text, can_gc);
}
fragment

View file

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

View file

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

View file

@ -24,6 +24,7 @@ use crate::dom::element::{Element, LayoutElementHelpers};
use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node;
use crate::dom::virtualmethods::VirtualMethods;
use crate::script_runtime::CanGc;
#[dom_struct]
pub struct HTMLFontElement {
@ -47,11 +48,13 @@ impl HTMLFontElement {
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLFontElement> {
Node::reflect_node_with_proto(
Box::new(HTMLFontElement::new_inherited(local_name, prefix, document)),
document,
proto,
can_gc,
)
}
@ -104,9 +107,9 @@ impl HTMLFontElementMethods for HTMLFontElement {
make_getter!(Size, "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>();
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>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLFormElement> {
Node::reflect_node_with_proto(
Box::new(HTMLFormElement::new_inherited(local_name, prefix, document)),
document,
proto,
can_gc,
)
}
@ -339,8 +341,8 @@ impl HTMLFormElementMethods for HTMLFormElement {
}
// https://html.spec.whatwg.org/multipage/#dom-form-reset
fn Reset(&self) {
self.reset(ResetFrom::FromForm);
fn Reset(&self, can_gc: CanGc) {
self.reset(ResetFrom::FromForm, can_gc);
}
// 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
fn SetRel(&self, rel: DOMString) {
fn SetRel(&self, rel: DOMString, can_gc: CanGc) {
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
@ -1230,7 +1232,7 @@ impl HTMLFormElement {
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
if self.marked_for_reset.get() {
return;
@ -1268,7 +1270,7 @@ impl HTMLFormElement {
NodeTypeId::Element(ElementTypeId::HTMLElement(
HTMLElementTypeId::HTMLOutputElement,
)) => {
child.downcast::<HTMLOutputElement>().unwrap().reset();
child.downcast::<HTMLOutputElement>().unwrap().reset(can_gc);
},
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLElement)) => {
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::htmlelement::HTMLElement;
use crate::dom::node::Node;
use crate::script_runtime::CanGc;
#[dom_struct]
pub struct HTMLFrameElement {
@ -33,6 +34,7 @@ impl HTMLFrameElement {
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLFrameElement> {
Node::reflect_node_with_proto(
Box::new(HTMLFrameElement::new_inherited(
@ -40,6 +42,7 @@ impl HTMLFrameElement {
)),
document,
proto,
can_gc,
)
}
}

View file

@ -13,6 +13,7 @@ use crate::dom::bindings::root::DomRoot;
use crate::dom::document::Document;
use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::{document_from_node, Node};
use crate::script_runtime::CanGc;
#[dom_struct]
pub struct HTMLFrameSetElement {
@ -36,6 +37,7 @@ impl HTMLFrameSetElement {
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLFrameSetElement> {
let n = Node::reflect_node_with_proto(
Box::new(HTMLFrameSetElement::new_inherited(
@ -43,6 +45,7 @@ impl HTMLFrameSetElement {
)),
document,
proto,
can_gc,
);
n.upcast::<Node>().set_weird_parser_insertion_mode();
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::userscripts::load_script;
use crate::dom::virtualmethods::VirtualMethods;
use crate::script_runtime::CanGc;
#[dom_struct]
pub struct HTMLHeadElement {
@ -40,11 +41,13 @@ impl HTMLHeadElement {
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLHeadElement> {
let n = Node::reflect_node_with_proto(
Box::new(HTMLHeadElement::new_inherited(local_name, prefix, document)),
document,
proto,
can_gc,
);
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::htmlelement::HTMLElement;
use crate::dom::node::Node;
use crate::script_runtime::CanGc;
#[derive(JSTraceable, MallocSizeOf)]
pub enum HeadingLevel {
@ -47,6 +48,7 @@ impl HTMLHeadingElement {
document: &Document,
proto: Option<HandleObject>,
level: HeadingLevel,
can_gc: CanGc,
) -> DomRoot<HTMLHeadingElement> {
Node::reflect_node_with_proto(
Box::new(HTMLHeadingElement::new_inherited(
@ -54,6 +56,7 @@ impl HTMLHeadingElement {
)),
document,
proto,
can_gc,
)
}
}

View file

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

View file

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

View file

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

View file

@ -1335,6 +1335,7 @@ impl HTMLImageElement {
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLImageElement> {
Node::reflect_node_with_proto(
Box::new(HTMLImageElement::new_inherited(
@ -1342,6 +1343,7 @@ impl HTMLImageElement {
)),
document,
proto,
can_gc,
)
}
@ -1546,10 +1548,10 @@ impl HTMLImageElementMethods for HTMLImageElement {
let image = DomRoot::downcast::<HTMLImageElement>(element).unwrap();
if let Some(w) = width {
image.SetWidth(w);
image.SetWidth(w, can_gc);
}
if let Some(h) = height {
image.SetHeight(h);
image.SetHeight(h, can_gc);
}
// 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
fn SetCrossOrigin(&self, value: Option<DOMString>) {
set_cross_origin_attribute(self.upcast::<Element>(), value);
fn SetCrossOrigin(&self, value: Option<DOMString>, can_gc: CanGc) {
set_cross_origin_attribute(self.upcast::<Element>(), value, can_gc);
}
// 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
fn SetWidth(&self, value: u32) {
image_dimension_setter(self.upcast(), local_name!("width"), value);
fn SetWidth(&self, value: u32, can_gc: CanGc) {
image_dimension_setter(self.upcast(), local_name!("width"), value, can_gc);
}
// 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
fn SetHeight(&self, value: u32) {
image_dimension_setter(self.upcast(), local_name!("height"), value);
fn SetHeight(&self, value: u32, can_gc: CanGc) {
image_dimension_setter(self.upcast(), local_name!("height"), value, can_gc);
}
// 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
fn SetReferrerPolicy(&self, value: DOMString) {
fn SetReferrerPolicy(&self, value: DOMString, can_gc: CanGc) {
let referrerpolicy_attr_name = local_name!("referrerpolicy");
let element = self.upcast::<Element>();
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 {
// 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.
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
// a dimension for rendering.
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 value = AttrValue::Dimension(value.to_string(), dim);
element.set_attribute(&attr, value);
element.set_attribute(&attr, value, can_gc);
}
/// Collect sequence of code points

View file

@ -326,6 +326,7 @@ impl HTMLInputElement {
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLInputElement> {
Node::reflect_node_with_proto(
Box::new(HTMLInputElement::new_inherited(
@ -333,6 +334,7 @@ impl HTMLInputElement {
)),
document,
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-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
if !self.does_value_as_number_apply() {
return Err(Error::InvalidState);
@ -738,7 +740,7 @@ impl HTMLInputElement {
}
// Step 11
self.SetValueAsNumber(value)
self.SetValueAsNumber(value, can_gc)
}
// 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
fn SetValue(&self, mut value: DOMString) -> ErrorResult {
fn SetValue(&self, mut value: DOMString, can_gc: CanGc) -> ErrorResult {
match self.value_mode() {
ValueMode::Value => {
// Step 3.
@ -1264,7 +1266,7 @@ impl HTMLInputElementMethods for HTMLInputElement {
},
ValueMode::Default | ValueMode::DefaultOn => {
self.upcast::<Element>()
.set_string_attribute(&local_name!("value"), value);
.set_string_attribute(&local_name!("value"), value, can_gc);
},
ValueMode::Filename => {
if value.is_empty() {
@ -1314,13 +1316,18 @@ impl HTMLInputElementMethods for HTMLInputElement {
// https://html.spec.whatwg.org/multipage/#dom-input-valueasdate
#[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);
if !self.does_value_as_date_apply() {
return Err(Error::InvalidState);
}
if value.is_null() {
return self.SetValue(DOMString::from(""));
return self.SetValue(DOMString::from(""), can_gc);
}
let mut msecs: f64 = 0.0;
// 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);
}
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 {
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
@ -1355,21 +1362,21 @@ impl HTMLInputElementMethods for HTMLInputElement {
}
// 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() {
Err(Error::Type("value is not finite".to_string()))
} else if !self.does_value_as_number_apply() {
Err(Error::InvalidState)
} 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) {
self.SetValue(converted)
self.SetValue(converted, can_gc)
} else {
// The most literal spec-compliant implementation would use bignum types so
// overflow is impossible, but just setting an overflow to the empty string
// matches Firefox's behavior. For example, try input.valueAsNumber=1e30 on
// 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
fn StepUp(&self, n: i32) -> ErrorResult {
self.step_up_or_down(n, StepDirection::Up)
fn StepUp(&self, n: i32, can_gc: CanGc) -> ErrorResult {
self.step_up_or_down(n, StepDirection::Up, can_gc)
}
// https://html.spec.whatwg.org/multipage/#dom-input-stepdown
fn StepDown(&self, n: i32) -> ErrorResult {
self.step_up_or_down(n, StepDirection::Down)
fn StepDown(&self, n: i32, can_gc: CanGc) -> ErrorResult {
self.step_up_or_down(n, StepDirection::Down, can_gc)
}
// https://html.spec.whatwg.org/multipage/#dom-cva-willvalidate
@ -2314,7 +2321,7 @@ impl VirtualMethods for HTMLInputElement {
// Step 1
(&ValueMode::Value, false, ValueMode::Default) |
(&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.");
},
@ -2326,6 +2333,7 @@ impl VirtualMethods for HTMLInputElement {
.map_or(DOMString::from(""), |a| {
DOMString::from(a.summarize().value)
}),
CanGc::note(),
)
.expect(
"Failed to set input value on type change to ValueMode::Value.",
@ -2337,7 +2345,7 @@ impl VirtualMethods for HTMLInputElement {
(_, _, 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.");
},
_ => {},
@ -2825,7 +2833,7 @@ impl Activatable for HTMLInputElement {
// FIXME (Manishearth): support document owners (needs ability to get parent browsing context)
// Check if document owner is fully active
if let Some(o) = self.form_owner() {
o.reset(ResetFrom::NotFromForm)
o.reset(ResetFrom::NotFromForm, CanGc::note())
}
},
InputType::Checkbox | InputType::Radio => {

View file

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

View file

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

View file

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

View file

@ -56,6 +56,7 @@ use crate::dom::virtualmethods::VirtualMethods;
use crate::fetch::create_a_potential_cors_request;
use crate::links::LinkRelations;
use crate::network_listener::{submit_timing, PreInvoke, ResourceTimingListener};
use crate::script_runtime::CanGc;
use crate::stylesheet_loader::{StylesheetContextSource, StylesheetLoader, StylesheetOwner};
#[derive(Clone, Copy, JSTraceable, MallocSizeOf, PartialEq)]
@ -137,6 +138,7 @@ impl HTMLLinkElement {
document: &Document,
proto: Option<HandleObject>,
creator: ElementCreator,
can_gc: CanGc,
) -> DomRoot<HTMLLinkElement> {
Node::reflect_node_with_proto(
Box::new(HTMLLinkElement::new_inherited(
@ -144,6 +146,7 @@ impl HTMLLinkElement {
)),
document,
proto,
can_gc,
)
}
@ -522,9 +525,9 @@ impl HTMLLinkElementMethods for HTMLLinkElement {
make_getter!(Rel, "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>()
.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
@ -602,8 +605,8 @@ impl HTMLLinkElementMethods for HTMLLinkElement {
}
// https://html.spec.whatwg.org/multipage/#dom-link-crossorigin
fn SetCrossOrigin(&self, value: Option<DOMString>) {
set_cross_origin_attribute(self.upcast::<Element>(), value);
fn SetCrossOrigin(&self, value: Option<DOMString>, can_gc: CanGc) {
set_cross_origin_attribute(self.upcast::<Element>(), value, can_gc);
}
// 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::htmlelement::HTMLElement;
use crate::dom::node::{Node, ShadowIncluding};
use crate::script_runtime::CanGc;
#[dom_struct]
pub struct HTMLMapElement {
@ -35,11 +36,13 @@ impl HTMLMapElement {
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLMapElement> {
Node::reflect_node_with_proto(
Box::new(HTMLMapElement::new_inherited(local_name, prefix, document)),
document,
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
// with the appropriate size.
if self.Controls() {
self.render_controls();
self.render_controls(can_gc);
}
let global = self.global();
@ -1887,7 +1887,7 @@ impl HTMLMediaElement {
.unwrap_or_else(|_| self.playback_position.get())
}
fn render_controls(&self) {
fn render_controls(&self, can_gc: CanGc) {
let element = self.htmlelement.upcast::<Element>();
if self.ready_state.get() < ReadyState::HaveMetadata || element.is_shadow_host() {
// Bail out if we have no metadata yet or
@ -1902,6 +1902,7 @@ impl HTMLMediaElement {
&document,
None,
ElementCreator::ScriptCreated,
can_gc,
);
let mut media_controls_script = resources::read_string(EmbedderResource::MediaControlsJS);
// 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);
script
.upcast::<Node>()
.SetTextContent(Some(DOMString::from(media_controls_script)));
.SetTextContent(Some(DOMString::from(media_controls_script)), can_gc);
if let Err(e) = shadow_root
.upcast::<Node>()
.AppendChild(script.upcast::<Node>())
@ -1930,10 +1931,11 @@ impl HTMLMediaElement {
&document,
None,
ElementCreator::ScriptCreated,
can_gc,
);
style
.upcast::<Node>()
.SetTextContent(Some(DOMString::from(media_controls_style)));
.SetTextContent(Some(DOMString::from(media_controls_style)), can_gc);
if let Err(e) = shadow_root
.upcast::<Node>()
@ -2078,8 +2080,8 @@ impl HTMLMediaElementMethods for HTMLMediaElement {
reflect_cross_origin_attribute(self.upcast::<Element>())
}
// https://html.spec.whatwg.org/multipage/#dom-media-crossOrigin
fn SetCrossOrigin(&self, value: Option<DOMString>) {
set_cross_origin_attribute(self.upcast::<Element>(), value);
fn SetCrossOrigin(&self, value: Option<DOMString>, can_gc: CanGc) {
set_cross_origin_attribute(self.upcast::<Element>(), value, can_gc);
}
// https://html.spec.whatwg.org/multipage/#dom-media-muted
@ -2473,7 +2475,7 @@ impl VirtualMethods for HTMLMediaElement {
},
local_name!("controls") => {
if mutation.new_value(attr).is_some() {
self.render_controls();
self.render_controls(CanGc::note());
} else {
self.remove_controls();
}

View file

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

View file

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

View file

@ -18,6 +18,7 @@ use crate::dom::element::Element;
use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node;
use crate::dom::nodelist::NodeList;
use crate::script_runtime::CanGc;
#[dom_struct]
pub struct HTMLMeterElement {
@ -44,6 +45,7 @@ impl HTMLMeterElement {
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLMeterElement> {
Node::reflect_node_with_proto(
Box::new(HTMLMeterElement::new_inherited(
@ -51,6 +53,7 @@ impl HTMLMeterElement {
)),
document,
proto,
can_gc,
)
}
}
@ -75,13 +78,13 @@ impl HTMLMeterElementMethods for HTMLMeterElement {
}
/// <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());
string_value.set_best_representation_of_the_floating_point_number();
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>
@ -95,13 +98,13 @@ impl HTMLMeterElementMethods for HTMLMeterElement {
}
/// <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());
string_value.set_best_representation_of_the_floating_point_number();
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>
@ -116,13 +119,13 @@ impl HTMLMeterElementMethods for HTMLMeterElement {
}
/// <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());
string_value.set_best_representation_of_the_floating_point_number();
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>
@ -141,13 +144,13 @@ impl HTMLMeterElementMethods for HTMLMeterElement {
}
/// <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());
string_value.set_best_representation_of_the_floating_point_number();
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>
@ -170,13 +173,13 @@ impl HTMLMeterElementMethods for HTMLMeterElement {
}
/// <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());
string_value.set_best_representation_of_the_floating_point_number();
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>
@ -195,12 +198,15 @@ impl HTMLMeterElementMethods for HTMLMeterElement {
}
/// <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());
string_value.set_best_representation_of_the_floating_point_number();
self.upcast::<Element>()
.set_string_attribute(&local_name!("optimum"), string_value);
self.upcast::<Element>().set_string_attribute(
&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::htmlelement::HTMLElement;
use crate::dom::node::Node;
use crate::script_runtime::CanGc;
#[dom_struct]
pub struct HTMLModElement {
@ -33,11 +34,13 @@ impl HTMLModElement {
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLModElement> {
Node::reflect_node_with_proto(
Box::new(HTMLModElement::new_inherited(local_name, prefix, document)),
document,
proto,
can_gc,
)
}
}

View file

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

View file

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

View file

@ -72,6 +72,7 @@ impl HTMLOptionElement {
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLOptionElement> {
Node::reflect_node_with_proto(
Box::new(HTMLOptionElement::new_inherited(
@ -79,6 +80,7 @@ impl HTMLOptionElement {
)),
document,
proto,
can_gc,
)
}
@ -196,7 +198,7 @@ impl HTMLOptionElementMethods for HTMLOptionElement {
let option = DomRoot::downcast::<HTMLOptionElement>(element).unwrap();
if !text.is_empty() {
option.upcast::<Node>().SetTextContent(Some(text))
option.upcast::<Node>().SetTextContent(Some(text), can_gc)
}
if let Some(val) = value {
@ -223,8 +225,8 @@ impl HTMLOptionElementMethods for HTMLOptionElement {
}
// https://html.spec.whatwg.org/multipage/#dom-option-text
fn SetText(&self, value: DOMString) {
self.upcast::<Node>().SetTextContent(Some(value))
fn SetText(&self, value: DOMString, can_gc: CanGc) {
self.upcast::<Node>().SetTextContent(Some(value), can_gc)
}
// 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::node::{document_from_node, Node};
use crate::dom::window::Window;
use crate::script_runtime::CanGc;
#[dom_struct]
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 document = document_from_node(&*root);
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>();
root.AppendChild(node)?;
}
@ -91,7 +93,12 @@ impl HTMLOptionsCollectionMethods for HTMLOptionsCollection {
}
// 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 {
// Step 2
let length = self.upcast().Length();
@ -101,7 +108,7 @@ impl HTMLOptionsCollectionMethods for HTMLOptionsCollection {
// Step 4
if n > 0 {
self.add_new_elements(n as u32)?;
self.add_new_elements(n as u32, can_gc)?;
}
// Step 5
@ -128,7 +135,7 @@ impl HTMLOptionsCollectionMethods for HTMLOptionsCollection {
}
/// <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 delta = length as i32 - current_length as i32;
match delta.cmp(&0) {
@ -140,7 +147,7 @@ impl HTMLOptionsCollectionMethods for HTMLOptionsCollection {
},
Ordering::Greater => {
// 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>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLOutputElement> {
Node::reflect_node_with_proto(
Box::new(HTMLOutputElement::new_inherited(
@ -60,11 +61,12 @@ impl HTMLOutputElement {
)),
document,
proto,
can_gc,
)
}
pub fn reset(&self) {
Node::string_replace_all(self.DefaultValue(), self.upcast::<Node>());
pub fn reset(&self, can_gc: CanGc) {
Node::string_replace_all(self.DefaultValue(), self.upcast::<Node>(), can_gc);
*self.default_value_override.borrow_mut() = None;
}
}
@ -89,10 +91,10 @@ impl HTMLOutputElementMethods for HTMLOutputElement {
}
// 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() {
// 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 {
// Step 2, if not returned from step 1
*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
fn SetValue(&self, value: DOMString) {
fn SetValue(&self, value: DOMString, can_gc: CanGc) {
*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

View file

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

View file

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

View file

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

View file

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

View file

@ -16,6 +16,7 @@ use crate::dom::element::Element;
use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node;
use crate::dom::nodelist::NodeList;
use crate::script_runtime::CanGc;
#[dom_struct]
pub struct HTMLProgressElement {
@ -41,6 +42,7 @@ impl HTMLProgressElement {
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLProgressElement> {
Node::reflect_node_with_proto(
Box::new(HTMLProgressElement::new_inherited(
@ -48,6 +50,7 @@ impl HTMLProgressElement {
)),
document,
proto,
can_gc,
)
}
}
@ -77,14 +80,17 @@ impl HTMLProgressElementMethods for HTMLProgressElement {
}
/// <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 {
let mut string_value = DOMString::from_string((*new_val).to_string());
string_value.set_best_representation_of_the_floating_point_number();
self.upcast::<Element>()
.set_string_attribute(&local_name!("value"), string_value);
self.upcast::<Element>().set_string_attribute(
&local_name!("value"),
string_value,
can_gc,
);
}
}
@ -106,14 +112,17 @@ impl HTMLProgressElementMethods for HTMLProgressElement {
}
/// <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 {
let mut string_value = DOMString::from_string((*new_val).to_string());
string_value.set_best_representation_of_the_floating_point_number();
self.upcast::<Element>()
.set_string_attribute(&local_name!("max"), string_value);
self.upcast::<Element>().set_string_attribute(
&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::htmlelement::HTMLElement;
use crate::dom::node::Node;
use crate::script_runtime::CanGc;
#[dom_struct]
pub struct HTMLQuoteElement {
@ -35,6 +36,7 @@ impl HTMLQuoteElement {
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLQuoteElement> {
Node::reflect_node_with_proto(
Box::new(HTMLQuoteElement::new_inherited(
@ -42,6 +44,7 @@ impl HTMLQuoteElement {
)),
document,
proto,
can_gc,
)
}
}

View file

@ -193,6 +193,7 @@ impl HTMLScriptElement {
document: &Document,
proto: Option<HandleObject>,
creator: ElementCreator,
can_gc: CanGc,
) -> DomRoot<HTMLScriptElement> {
Node::reflect_node_with_proto(
Box::new(HTMLScriptElement::new_inherited(
@ -200,6 +201,7 @@ impl HTMLScriptElement {
)),
document,
proto,
can_gc,
)
}
@ -1311,10 +1313,10 @@ impl HTMLScriptElementMethods for HTMLScriptElement {
}
// 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.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
@ -1348,8 +1350,8 @@ impl HTMLScriptElementMethods for HTMLScriptElement {
}
// https://html.spec.whatwg.org/multipage/#dom-script-crossorigin
fn SetCrossOrigin(&self, value: Option<DOMString>) {
set_cross_origin_attribute(self.upcast::<Element>(), value);
fn SetCrossOrigin(&self, value: Option<DOMString>, can_gc: CanGc) {
set_cross_origin_attribute(self.upcast::<Element>(), value, can_gc);
}
// 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
fn SetText(&self, value: DOMString) {
self.upcast::<Node>().SetTextContent(Some(value))
fn SetText(&self, value: DOMString, can_gc: CanGc) {
self.upcast::<Node>().SetTextContent(Some(value), can_gc)
}
}

View file

@ -98,6 +98,7 @@ impl HTMLSelectElement {
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLSelectElement> {
let n = Node::reflect_node_with_proto(
Box::new(HTMLSelectElement::new_inherited(
@ -105,6 +106,7 @@ impl HTMLSelectElement {
)),
document,
proto,
can_gc,
);
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
fn SetLength(&self, length: u32) {
self.Options().SetLength(length)
fn SetLength(&self, length: u32, can_gc: CanGc) {
self.Options().SetLength(length, can_gc)
}
// 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
fn IndexedSetter(&self, index: u32, value: Option<&HTMLOptionElement>) -> ErrorResult {
self.Options().IndexedSetter(index, value)
fn IndexedSetter(
&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

View file

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

View file

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

View file

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

View file

@ -11,6 +11,7 @@ use crate::dom::bindings::root::DomRoot;
use crate::dom::document::Document;
use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node;
use crate::script_runtime::CanGc;
#[dom_struct]
pub struct HTMLTableCaptionElement {
@ -34,6 +35,7 @@ impl HTMLTableCaptionElement {
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLTableCaptionElement> {
let n = Node::reflect_node_with_proto(
Box::new(HTMLTableCaptionElement::new_inherited(
@ -41,6 +43,7 @@ impl HTMLTableCaptionElement {
)),
document,
proto,
can_gc,
);
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::node::{LayoutNodeHelpers, Node};
use crate::dom::virtualmethods::VirtualMethods;
use crate::script_runtime::CanGc;
const DEFAULT_COLSPAN: u32 = 1;
const DEFAULT_ROWSPAN: u32 = 1;
@ -48,6 +49,7 @@ impl HTMLTableCellElement {
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLTableCellElement> {
let n = Node::reflect_node_with_proto(
Box::new(HTMLTableCellElement::new_inherited(
@ -55,6 +57,7 @@ impl HTMLTableCellElement {
)),
document,
proto,
can_gc,
);
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::node::Node;
use crate::dom::virtualmethods::VirtualMethods;
use crate::script_runtime::CanGc;
const DEFAULT_SPAN: u32 = 1;
@ -43,6 +44,7 @@ impl HTMLTableColElement {
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLTableColElement> {
let n = Node::reflect_node_with_proto(
Box::new(HTMLTableColElement::new_inherited(
@ -50,6 +52,7 @@ impl HTMLTableColElement {
)),
document,
proto,
can_gc,
);
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::node::{document_from_node, window_from_node, Node};
use crate::dom::virtualmethods::VirtualMethods;
use crate::script_runtime::CanGc;
#[dom_struct]
pub struct HTMLTableElement {
@ -75,6 +76,7 @@ impl HTMLTableElement {
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLTableElement> {
let n = Node::reflect_node_with_proto(
Box::new(HTMLTableElement::new_inherited(
@ -82,6 +84,7 @@ impl HTMLTableElement {
)),
document,
proto,
can_gc,
);
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-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) {
return section;
}
let section =
HTMLTableSectionElement::new(atom.clone(), None, &document_from_node(self), None);
let section = HTMLTableSectionElement::new(
atom.clone(),
None,
&document_from_node(self),
None,
can_gc,
);
match *atom {
local_name!("thead") => self.SetTHead(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
fn CreateCaption(&self) -> DomRoot<HTMLTableCaptionElement> {
fn CreateCaption(&self, can_gc: CanGc) -> DomRoot<HTMLTableCaptionElement> {
match self.GetCaption() {
Some(caption) => caption,
None => {
@ -215,6 +227,7 @@ impl HTMLTableElementMethods for HTMLTableElement {
None,
&document_from_node(self),
None,
can_gc,
);
self.SetCaption(Some(&caption))
.expect("Generated caption is invalid");
@ -243,8 +256,8 @@ impl HTMLTableElementMethods for HTMLTableElement {
}
// https://html.spec.whatwg.org/multipage/#dom-table-createthead
fn CreateTHead(&self) -> DomRoot<HTMLTableSectionElement> {
self.create_section_of_type(&local_name!("thead"))
fn CreateTHead(&self, can_gc: CanGc) -> DomRoot<HTMLTableSectionElement> {
self.create_section_of_type(&local_name!("thead"), can_gc)
}
// 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
fn CreateTFoot(&self) -> DomRoot<HTMLTableSectionElement> {
self.create_section_of_type(&local_name!("tfoot"))
fn CreateTFoot(&self, can_gc: CanGc) -> DomRoot<HTMLTableSectionElement> {
self.create_section_of_type(&local_name!("tfoot"), can_gc)
}
// 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
fn CreateTBody(&self) -> DomRoot<HTMLTableSectionElement> {
fn CreateTBody(&self, can_gc: CanGc) -> DomRoot<HTMLTableSectionElement> {
let tbody = HTMLTableSectionElement::new(
local_name!("tbody"),
None,
&document_from_node(self),
None,
can_gc,
);
let node = self.upcast::<Node>();
let last_tbody = node
@ -325,7 +339,7 @@ impl HTMLTableElementMethods for HTMLTableElement {
}
// 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 number_of_row_elements = rows.Length();
@ -333,8 +347,13 @@ impl HTMLTableElementMethods for HTMLTableElement {
return Err(Error::IndexSize);
}
let new_row =
HTMLTableRowElement::new(local_name!("tr"), None, &document_from_node(self), None);
let new_row = HTMLTableRowElement::new(
local_name!("tr"),
None,
&document_from_node(self),
None,
can_gc,
);
let node = self.upcast::<Node>();
if number_of_row_elements == 0 {
@ -351,7 +370,7 @@ impl HTMLTableElementMethods for HTMLTableElement {
.AppendChild(new_row.upcast::<Node>())
.expect("InsertRow failed to append first row.");
} else {
let tbody = self.CreateTBody();
let tbody = self.CreateTBody(can_gc);
node.AppendChild(tbody.upcast())
.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::node::{window_from_node, Node};
use crate::dom::virtualmethods::VirtualMethods;
use crate::script_runtime::CanGc;
#[derive(JSTraceable)]
struct CellsFilter;
@ -59,6 +60,7 @@ impl HTMLTableRowElement {
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLTableRowElement> {
let n = Node::reflect_node_with_proto(
Box::new(HTMLTableRowElement::new_inherited(
@ -66,6 +68,7 @@ impl HTMLTableRowElement {
)),
document,
proto,
can_gc,
);
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
fn InsertCell(&self, index: i32) -> Fallible<DomRoot<HTMLElement>> {
fn InsertCell(&self, index: i32, can_gc: CanGc) -> Fallible<DomRoot<HTMLElement>> {
let node = self.upcast::<Node>();
node.insert_cell_or_row(
index,
|| 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::node::{window_from_node, Node};
use crate::dom::virtualmethods::VirtualMethods;
use crate::script_runtime::CanGc;
#[dom_struct]
pub struct HTMLTableSectionElement {
@ -44,6 +45,7 @@ impl HTMLTableSectionElement {
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLTableSectionElement> {
let n = Node::reflect_node_with_proto(
Box::new(HTMLTableSectionElement::new_inherited(
@ -51,6 +53,7 @@ impl HTMLTableSectionElement {
)),
document,
proto,
can_gc,
);
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
fn InsertRow(&self, index: i32) -> Fallible<DomRoot<HTMLElement>> {
fn InsertRow(&self, index: i32, can_gc: CanGc) -> Fallible<DomRoot<HTMLElement>> {
let node = self.upcast::<Node>();
node.insert_cell_or_row(
index,
|| 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>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLTemplateElement> {
let n = Node::reflect_node_with_proto(
Box::new(HTMLTemplateElement::new_inherited(
@ -51,6 +52,7 @@ impl HTMLTemplateElement {
)),
document,
proto,
can_gc,
);
n.upcast::<Node>().set_weird_parser_insertion_mode();
@ -64,7 +66,7 @@ impl HTMLTemplateElementMethods for HTMLTemplateElement {
self.contents.or_init(|| {
let doc = document_from_node(self);
doc.appropriate_template_contents_owner_document(can_gc)
.CreateDocumentFragment()
.CreateDocumentFragment(can_gc)
})
}
}

View file

@ -176,6 +176,7 @@ impl HTMLTextAreaElement {
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLTextAreaElement> {
Node::reflect_node_with_proto(
Box::new(HTMLTextAreaElement::new_inherited(
@ -183,6 +184,7 @@ impl HTMLTextAreaElement {
)),
document,
proto,
can_gc,
)
}
@ -306,8 +308,8 @@ impl HTMLTextAreaElementMethods for HTMLTextAreaElement {
}
// https://html.spec.whatwg.org/multipage/#dom-textarea-defaultvalue
fn SetDefaultValue(&self, value: DOMString) {
self.upcast::<Node>().SetTextContent(Some(value));
fn SetDefaultValue(&self, value: DOMString, can_gc: CanGc) {
self.upcast::<Node>().SetTextContent(Some(value), can_gc);
// 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

View file

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

View file

@ -17,6 +17,7 @@ use crate::dom::document::Document;
use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::{BindContext, ChildrenMutation, Node};
use crate::dom::virtualmethods::VirtualMethods;
use crate::script_runtime::CanGc;
#[dom_struct]
pub struct HTMLTitleElement {
@ -42,6 +43,7 @@ impl HTMLTitleElement {
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLTitleElement> {
Node::reflect_node_with_proto(
Box::new(HTMLTitleElement::new_inherited(
@ -49,6 +51,7 @@ impl HTMLTitleElement {
)),
document,
proto,
can_gc,
)
}
@ -67,8 +70,8 @@ impl HTMLTitleElementMethods for HTMLTitleElement {
}
// https://html.spec.whatwg.org/multipage/#dom-title-text
fn SetText(&self, value: DOMString) {
self.upcast::<Node>().SetTextContent(Some(value))
fn SetText(&self, value: DOMString, can_gc: CanGc) {
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::node::Node;
use crate::dom::texttrack::TextTrack;
use crate::script_runtime::CanGc;
#[derive(Clone, Copy, JSTraceable, MallocSizeOf, PartialEq)]
#[repr(u16)]
@ -54,6 +55,7 @@ impl HTMLTrackElement {
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLTrackElement> {
let track = TextTrack::new(
document.window(),
@ -70,6 +72,7 @@ impl HTMLTrackElement {
)),
document,
proto,
can_gc,
)
}
}

View file

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

View file

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

View file

@ -89,6 +89,7 @@ impl HTMLVideoElement {
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLVideoElement> {
Node::reflect_node_with_proto(
Box::new(HTMLVideoElement::new_inherited(
@ -96,6 +97,7 @@ impl HTMLVideoElement {
)),
document,
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 {
use $crate::dom::bindings::inheritance::Castable;
use $crate::dom::element::Element;
use $crate::script_runtime::CanGc;
let value = if value < 0 {
return Err($crate::dom::bindings::error::Error::IndexSize);
@ -40,7 +41,7 @@ macro_rules! make_limited_int_setter(
};
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(())
}
);
@ -52,9 +53,10 @@ macro_rules! make_int_setter(
fn $attr(&self, value: i32) {
use $crate::dom::bindings::inheritance::Castable;
use $crate::dom::element::Element;
use $crate::script_runtime::CanGc;
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) => {
@ -111,9 +113,10 @@ macro_rules! make_url_setter(
fn $attr(&self, value: USVString) {
use $crate::dom::bindings::inheritance::Castable;
use $crate::dom::element::Element;
use $crate::script_runtime::CanGc;
let element = self.upcast::<Element>();
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) {
use $crate::dom::bindings::inheritance::Castable;
use $crate::dom::element::Element;
use $crate::script_runtime::CanGc;
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) {
use $crate::dom::bindings::inheritance::Castable;
use $crate::dom::element::Element;
use $crate::script_runtime::CanGc;
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::element::Element;
use $crate::dom::values::UNSIGNED_LONG_MAX;
use $crate::script_runtime::CanGc;
let value = if value > UNSIGNED_LONG_MAX {
$default
} else {
value
};
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) => {
@ -227,6 +233,7 @@ macro_rules! make_limited_uint_setter(
use $crate::dom::bindings::inheritance::Castable;
use $crate::dom::element::Element;
use $crate::dom::values::UNSIGNED_LONG_MAX;
use $crate::script_runtime::CanGc;
let value = if value == 0 {
return Err($crate::dom::bindings::error::Error::IndexSize);
} else if value > UNSIGNED_LONG_MAX {
@ -235,7 +242,7 @@ macro_rules! make_limited_uint_setter(
value
};
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(())
}
);
@ -250,8 +257,9 @@ macro_rules! make_atomic_setter(
fn $attr(&self, value: DOMString) {
use $crate::dom::bindings::inheritance::Castable;
use $crate::dom::element::Element;
use $crate::script_runtime::CanGc;
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::element::Element;
use style::attr::AttrValue;
use $crate::script_runtime::CanGc;
let element = self.upcast::<Element>();
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) {
use $crate::dom::bindings::inheritance::Castable;
use $crate::dom::element::Element;
use $crate::script_runtime::CanGc;
let element = self.upcast::<Element>();
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) {
use $crate::dom::bindings::inheritance::Castable;
use $crate::dom::element::Element;
use $crate::script_runtime::CanGc;
let element = self.upcast::<Element>();
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>
pub fn before(&self, nodes: Vec<NodeOrString>) -> ErrorResult {
pub fn before(&self, nodes: Vec<NodeOrString>, can_gc: CanGc) -> ErrorResult {
// Step 1.
let parent = &self.parent_node;
@ -871,7 +871,9 @@ impl Node {
let viable_previous_sibling = first_node_not_in(self.preceding_siblings(), &nodes);
// 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.
let viable_previous_sibling = match viable_previous_sibling {
@ -886,7 +888,7 @@ impl Node {
}
/// <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.
let parent = &self.parent_node;
@ -900,7 +902,9 @@ impl Node {
let viable_next_sibling = first_node_not_in(self.following_siblings(), &nodes);
// 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.
Node::pre_insert(&node, &parent, viable_next_sibling.as_deref())?;
@ -909,7 +913,7 @@ impl Node {
}
/// <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.
let parent = if let Some(parent) = self.GetParentNode() {
parent
@ -920,7 +924,9 @@ impl Node {
// Step 3.
let viable_next_sibling = first_node_not_in(self.following_siblings(), &nodes);
// 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) {
// Step 5.
parent.ReplaceChild(&node, self)?;
@ -932,29 +938,29 @@ impl Node {
}
/// <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.
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.
let first_child = self.first_child.get();
Node::pre_insert(&node, self, first_child.as_deref()).map(|_| ())
}
/// <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.
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.
self.AppendChild(&node).map(|_| ())
}
/// <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.
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.
Node::ensure_pre_insertion_validity(&node, self, None)?;
// Step 3.
@ -1767,23 +1773,24 @@ fn as_uintptr<T>(t: &T) -> uintptr_t {
}
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
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>(
node: Box<N>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<N>
where
N: DerivedFrom<Node> + DomObject + DomObjectWrap,
{
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 {
@ -2151,11 +2158,11 @@ impl Node {
}
/// <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 {
Node::replace_all(None, parent);
} 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);
};
}
@ -2250,6 +2257,7 @@ impl Node {
Some(doctype.public_id().clone()),
Some(doctype.system_id().clone()),
&document,
can_gc,
);
DomRoot::upcast::<Node>(doctype)
},
@ -2263,16 +2271,17 @@ impl Node {
attr.namespace().clone(),
attr.prefix().cloned(),
None,
can_gc,
);
DomRoot::upcast::<Node>(attr)
},
NodeTypeId::DocumentFragment(_) => {
let doc_fragment = DocumentFragment::new(&document);
let doc_fragment = DocumentFragment::new(&document, can_gc);
DomRoot::upcast::<Node>(doc_fragment)
},
NodeTypeId::CharacterData(_) => {
let cdata = node.downcast::<CharacterData>().unwrap();
cdata.clone_with_data(cdata.Data(), &document)
cdata.clone_with_data(cdata.Data(), &document, can_gc)
},
NodeTypeId::Document(_) => {
let document = node.downcast::<Document>().unwrap();
@ -2349,6 +2358,7 @@ impl Node {
attr.name().clone(),
attr.namespace().clone(),
attr.prefix().cloned(),
can_gc,
);
}
},
@ -2610,7 +2620,7 @@ impl NodeMethods for Node {
}
/// <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();
match self.type_id() {
NodeTypeId::DocumentFragment(_) | NodeTypeId::Element(..) => {
@ -2618,7 +2628,9 @@ impl NodeMethods for Node {
let node = if value.is_empty() {
None
} else {
Some(DomRoot::upcast(self.owner_doc().CreateTextNode(value)))
Some(DomRoot::upcast(
self.owner_doc().CreateTextNode(value, can_gc),
))
};
// Step 3.

View file

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

View file

@ -561,7 +561,7 @@ impl RangeMethods for Range {
let end_offset = self.end_offset();
// Step 1.
let fragment = DocumentFragment::new(&start_node.owner_doc());
let fragment = DocumentFragment::new(&start_node.owner_doc(), can_gc);
// Step 2.
if self.start() == self.end() {
@ -574,7 +574,7 @@ impl RangeMethods for Range {
let data = cdata
.SubstringData(start_offset, end_offset - start_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 4.3.
fragment.upcast::<Node>().AppendChild(&clone)?;
// Step 4.4
@ -597,7 +597,7 @@ impl RangeMethods for Range {
let data = cdata
.SubstringData(start_offset, start_node.len() - start_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 13.3.
fragment.upcast::<Node>().AppendChild(&clone)?;
} else {
@ -635,7 +635,7 @@ impl RangeMethods for Range {
assert!(child == end_node);
// Steps 16.1-2.
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.
fragment.upcast::<Node>().AppendChild(&clone)?;
} else {
@ -667,7 +667,7 @@ impl RangeMethods for Range {
let end_offset = self.end_offset();
// Step 1.
let fragment = DocumentFragment::new(&start_node.owner_doc());
let fragment = DocumentFragment::new(&start_node.owner_doc(), can_gc);
// Step 2.
if self.collapsed() {
@ -807,7 +807,7 @@ impl RangeMethods for Range {
/// <https://dom.spec.whatwg.org/#dom-range-insertnode>
/// <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_offset = self.start_offset();
@ -848,7 +848,7 @@ impl RangeMethods for Range {
let split_text;
let reference_node = match start_node.downcast::<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);
assert!(new_reference.GetParentNode().as_deref() == Some(&parent));
Some(new_reference)
@ -1006,7 +1006,7 @@ impl RangeMethods for Range {
Node::replace_all(None, new_parent);
// Step 5.
self.InsertNode(new_parent)?;
self.InsertNode(new_parent, can_gc)?;
// Step 6.
new_parent.AppendChild(fragment.upcast())?;
@ -1086,7 +1086,7 @@ impl RangeMethods for Range {
};
// 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.
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()));
},
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()));
},
ParseOperation::AppendBeforeSibling { sibling, node } => {
@ -477,6 +477,7 @@ impl Tokenizer {
Some(DOMString::from(public_id)),
Some(DOMString::from(system_id)),
document,
can_gc,
);
document
@ -490,7 +491,12 @@ impl Tokenizer {
.downcast::<Element>()
.expect("tried to set attrs on non-Element in HTML parsing");
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 } => {
@ -549,6 +555,7 @@ impl Tokenizer {
DOMString::from(target),
DOMString::from(data),
document,
can_gc,
);
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_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()));
doc_body
.AppendChild(&DomRoot::upcast::<Node>(img))
@ -1053,7 +1053,7 @@ fn insert(
if let Some(text) = text {
text.upcast::<CharacterData>().append_data(&t);
} 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();
}
},
@ -1145,7 +1145,12 @@ impl TreeSink for Sink {
#[allow(crown::unrooted_must_root)]
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())
}
@ -1156,6 +1161,7 @@ impl TreeSink for Sink {
DOMString::from(String::from(target)),
DOMString::from(String::from(data)),
doc,
CanGc::note(),
);
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(system_id))),
doc,
CanGc::note(),
);
doc.upcast::<Node>()
.AppendChild(doctype.upcast())
@ -1264,6 +1271,7 @@ impl TreeSink for Sink {
attr.name,
DOMString::from(String::from(attr.value)),
None,
CanGc::note(),
);
}
}
@ -1377,7 +1385,7 @@ fn create_element_for_token(
// Step 8
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"

View file

@ -15,6 +15,7 @@ use crate::dom::document::Document;
use crate::dom::element::Element;
use crate::dom::node::{window_from_node, Node};
use crate::dom::virtualmethods::VirtualMethods;
use crate::script_runtime::CanGc;
#[dom_struct]
pub struct SVGElement {
@ -48,11 +49,13 @@ impl SVGElement {
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<SVGElement> {
Node::reflect_node_with_proto(
Box::new(SVGElement::new_inherited(tag_name, prefix, document)),
document,
proto,
can_gc,
)
}
}
@ -83,8 +86,8 @@ impl SVGElementMethods for SVGElement {
}
// https://html.spec.whatwg.org/multipage/#dom-fe-autofocus
fn SetAutofocus(&self, autofocus: bool) {
fn SetAutofocus(&self, autofocus: bool, can_gc: CanGc) {
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::svggraphicselement::SVGGraphicsElement;
use crate::dom::virtualmethods::VirtualMethods;
use crate::script_runtime::CanGc;
const DEFAULT_WIDTH: u32 = 300;
const DEFAULT_HEIGHT: u32 = 150;
@ -43,11 +44,13 @@ impl SVGSVGElement {
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<SVGSVGElement> {
Node::reflect_node_with_proto(
Box::new(SVGSVGElement::new_inherited(local_name, prefix, document)),
document,
proto,
can_gc,
)
}
}

View file

@ -33,19 +33,21 @@ impl Text {
}
}
pub fn new(text: DOMString, document: &Document) -> DomRoot<Text> {
Self::new_with_proto(text, document, None)
pub fn new(text: DOMString, document: &Document, can_gc: CanGc) -> DomRoot<Text> {
Self::new_with_proto(text, document, None, can_gc)
}
fn new_with_proto(
text: DOMString,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<Text> {
Node::reflect_node_with_proto(
Box::new(Text::new_inherited(text, document)),
document,
proto,
can_gc,
)
}
}
@ -55,16 +57,16 @@ impl TextMethods for Text {
fn Constructor(
window: &Window,
proto: Option<HandleObject>,
_can_gc: CanGc,
can_gc: CanGc,
text: DOMString,
) -> Fallible<DomRoot<Text>> {
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/#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>();
// Step 1.
let length = cdata.Length();
@ -79,7 +81,7 @@ impl TextMethods for Text {
// Step 5.
let node = self.upcast::<Node>();
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.
let parent = node.GetParentNode();
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)
},
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) => {
devtools::handle_modify_rule(&documents, id, node_id, modifications)