Files
servo/components/script/dom/html/htmllabelelement.rs
Simon Wülker c4ae451612 Turn all commented links before functions into doccomments (#40331)
Servo has a lot of comments like this:
```rust
// https://example-spec.com/#do-the-thing
fn do_the_thing() {}
```
and I keep turning these into doc comments whenever I'm working close to
one of them. Doing so allows me to hover over a function call in an IDE
and open its specification without having to jump to the function
definition first. This change fixes all of these comments at once.

This was done using `find components -name '*.rs' -exec perl -i -0777
-pe 's|^([ \t]*)// (https?://.*)\n\1(fn )|\1/// <$2>\n\1$3|mg' {} +`.

Note that these comments should be doc comments even within trait `impl`
blocks, because rustdoc will use them as fallback documentation when the
method definition on the trait does not have documentation.

Testing: Comments only, no testing required
Preparation for https://github.com/servo/servo/pull/39552

---------

Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
2025-11-01 05:32:45 +00:00

198 lines
6.9 KiB
Rust

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix, local_name, ns};
use js::rust::HandleObject;
use style::attr::AttrValue;
use crate::dom::activation::Activatable;
use crate::dom::attr::Attr;
use crate::dom::bindings::codegen::Bindings::AttrBinding::AttrMethods;
use crate::dom::bindings::codegen::Bindings::ElementBinding::ElementMethods;
use crate::dom::bindings::codegen::Bindings::HTMLElementBinding::HTMLElementMethods;
use crate::dom::bindings::codegen::Bindings::HTMLLabelElementBinding::HTMLLabelElementMethods;
use crate::dom::bindings::codegen::Bindings::NodeBinding::{GetRootNodeOptions, NodeMethods};
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::DOMString;
use crate::dom::document::Document;
use crate::dom::element::{AttributeMutation, Element};
use crate::dom::event::Event;
use crate::dom::eventtarget::EventTarget;
use crate::dom::html::htmlelement::HTMLElement;
use crate::dom::html::htmlformelement::{FormControl, FormControlElementHelpers, HTMLFormElement};
use crate::dom::node::{Node, ShadowIncluding};
use crate::dom::virtualmethods::VirtualMethods;
use crate::script_runtime::CanGc;
#[dom_struct]
pub(crate) struct HTMLLabelElement {
htmlelement: HTMLElement,
}
impl HTMLLabelElement {
fn new_inherited(
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
) -> HTMLLabelElement {
HTMLLabelElement {
htmlelement: HTMLElement::new_inherited(local_name, prefix, document),
}
}
#[cfg_attr(crown, allow(crown::unrooted_must_root))]
pub(crate) fn new(
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLLabelElement> {
Node::reflect_node_with_proto(
Box::new(HTMLLabelElement::new_inherited(
local_name, prefix, document,
)),
document,
proto,
can_gc,
)
}
}
impl Activatable for HTMLLabelElement {
fn as_element(&self) -> &Element {
self.upcast::<Element>()
}
fn is_instance_activatable(&self) -> bool {
true
}
// https://html.spec.whatwg.org/multipage/#the-label-element:activation_behaviour
// Basically this is telling us that if activation bubbles up to the label
// at all, we are free to do an implementation-dependent thing;
// firing a click event is an example, and the precise details of that
// click event (e.g. isTrusted) are not specified.
fn activation_behavior(&self, _event: &Event, _target: &EventTarget, can_gc: CanGc) {
if let Some(e) = self.GetControl() {
e.Click(can_gc);
}
}
}
impl HTMLLabelElementMethods<crate::DomTypeHolder> for HTMLLabelElement {
/// <https://html.spec.whatwg.org/multipage/#dom-fae-form>
fn GetForm(&self) -> Option<DomRoot<HTMLFormElement>> {
self.form_owner()
}
// https://html.spec.whatwg.org/multipage/#dom-label-htmlfor
make_getter!(HtmlFor, "for");
// https://html.spec.whatwg.org/multipage/#dom-label-htmlfor
make_atomic_setter!(SetHtmlFor, "for");
/// <https://html.spec.whatwg.org/multipage/#dom-label-control>
fn GetControl(&self) -> Option<DomRoot<HTMLElement>> {
let for_attr = match self
.upcast::<Element>()
.get_attribute(&ns!(), &local_name!("for"))
{
Some(for_attr) => for_attr,
None => return self.first_labelable_descendant(),
};
let for_value = for_attr.Value();
// "If the attribute is specified and there is an element in the tree
// whose ID is equal to the value of the for attribute, and the first
// such element in tree order is a labelable element, then that
// element is the label element's labeled control."
// Two subtle points here: we need to search the _tree_, which is
// not necessarily the document if we're detached from the document,
// and we only consider one element even if a later element with
// the same ID is labelable.
let maybe_found = self
.upcast::<Node>()
.GetRootNode(&GetRootNodeOptions::empty())
.traverse_preorder(ShadowIncluding::No)
.find_map(|e| {
if let Some(htmle) = e.downcast::<HTMLElement>() {
if htmle.upcast::<Element>().Id() == for_value {
Some(DomRoot::from_ref(htmle))
} else {
None
}
} else {
None
}
});
// We now have the element that we would return, but only return it
// if it's labelable.
if let Some(ref maybe_labelable) = maybe_found {
if maybe_labelable.is_labelable_element() {
return maybe_found;
}
}
None
}
}
impl VirtualMethods for HTMLLabelElement {
fn super_type(&self) -> Option<&dyn VirtualMethods> {
Some(self.upcast::<HTMLElement>() as &dyn VirtualMethods)
}
fn parse_plain_attribute(&self, name: &LocalName, value: DOMString) -> AttrValue {
match name {
&local_name!("for") => AttrValue::from_atomic(value.into()),
_ => self
.super_type()
.unwrap()
.parse_plain_attribute(name, value),
}
}
fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) {
self.super_type()
.unwrap()
.attribute_mutated(attr, mutation, can_gc);
if *attr.local_name() == local_name!("form") {
self.form_attribute_mutated(mutation, can_gc);
}
}
}
impl HTMLLabelElement {
pub(crate) fn first_labelable_descendant(&self) -> Option<DomRoot<HTMLElement>> {
self.upcast::<Node>()
.traverse_preorder(ShadowIncluding::No)
.filter_map(DomRoot::downcast::<HTMLElement>)
.find(|elem| elem.is_labelable_element())
}
}
impl FormControl for HTMLLabelElement {
fn form_owner(&self) -> Option<DomRoot<HTMLFormElement>> {
self.GetControl()
.map(DomRoot::upcast::<Element>)
.and_then(|elem| {
elem.as_maybe_form_control()
.and_then(|control| control.form_owner())
})
}
fn set_form_owner(&self, _: Option<&HTMLFormElement>) {
// Label is a special case for form owner, it reflects its control's
// form owner. Therefore it doesn't hold form owner itself.
}
fn to_element(&self) -> &Element {
self.upcast::<Element>()
}
}