mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
CanGc changes from fontfaceset.rs (#33920)
* CanGc changes from fontfaceset.rs Signed-off-by: L Ashwin B <lashwinib@gmail.com> * Update components/script/dom/bindings/codegen/Bindings.conf Co-authored-by: Josh Matthews <josh@joshmatthews.net> Signed-off-by: chickenleaf <lashwinib@gmail.com> --------- Signed-off-by: L Ashwin B <lashwinib@gmail.com> Signed-off-by: chickenleaf <lashwinib@gmail.com> Co-authored-by: Josh Matthews <josh@joshmatthews.net>
This commit is contained in:
parent
66695d2f7e
commit
9acb25521e
32 changed files with 425 additions and 274 deletions
|
@ -737,8 +737,13 @@ impl CanvasState {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowcolor
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowcolor
|
||||||
pub fn set_shadow_color(&self, canvas: Option<&HTMLCanvasElement>, value: DOMString) {
|
pub fn set_shadow_color(
|
||||||
if let Ok(rgba) = parse_color(canvas, &value) {
|
&self,
|
||||||
|
canvas: Option<&HTMLCanvasElement>,
|
||||||
|
value: DOMString,
|
||||||
|
can_gc: CanGc,
|
||||||
|
) {
|
||||||
|
if let Ok(rgba) = parse_color(canvas, &value, can_gc) {
|
||||||
self.state.borrow_mut().shadow_color = rgba;
|
self.state.borrow_mut().shadow_color = rgba;
|
||||||
self.send_canvas_2d_msg(Canvas2dMsg::SetShadowColor(rgba))
|
self.send_canvas_2d_msg(Canvas2dMsg::SetShadowColor(rgba))
|
||||||
}
|
}
|
||||||
|
@ -766,10 +771,11 @@ impl CanvasState {
|
||||||
&self,
|
&self,
|
||||||
canvas: Option<&HTMLCanvasElement>,
|
canvas: Option<&HTMLCanvasElement>,
|
||||||
value: StringOrCanvasGradientOrCanvasPattern,
|
value: StringOrCanvasGradientOrCanvasPattern,
|
||||||
|
can_gc: CanGc,
|
||||||
) {
|
) {
|
||||||
match value {
|
match value {
|
||||||
StringOrCanvasGradientOrCanvasPattern::String(string) => {
|
StringOrCanvasGradientOrCanvasPattern::String(string) => {
|
||||||
if let Ok(rgba) = parse_color(canvas, &string) {
|
if let Ok(rgba) = parse_color(canvas, &string, can_gc) {
|
||||||
self.state.borrow_mut().stroke_style = CanvasFillOrStrokeStyle::Color(rgba);
|
self.state.borrow_mut().stroke_style = CanvasFillOrStrokeStyle::Color(rgba);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -809,10 +815,11 @@ impl CanvasState {
|
||||||
&self,
|
&self,
|
||||||
canvas: Option<&HTMLCanvasElement>,
|
canvas: Option<&HTMLCanvasElement>,
|
||||||
value: StringOrCanvasGradientOrCanvasPattern,
|
value: StringOrCanvasGradientOrCanvasPattern,
|
||||||
|
can_gc: CanGc,
|
||||||
) {
|
) {
|
||||||
match value {
|
match value {
|
||||||
StringOrCanvasGradientOrCanvasPattern::String(string) => {
|
StringOrCanvasGradientOrCanvasPattern::String(string) => {
|
||||||
if let Ok(rgba) = parse_color(canvas, &string) {
|
if let Ok(rgba) = parse_color(canvas, &string, can_gc) {
|
||||||
self.state.borrow_mut().fill_style = CanvasFillOrStrokeStyle::Color(rgba);
|
self.state.borrow_mut().fill_style = CanvasFillOrStrokeStyle::Color(rgba);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1002,6 +1009,7 @@ impl CanvasState {
|
||||||
x: f64,
|
x: f64,
|
||||||
y: f64,
|
y: f64,
|
||||||
max_width: Option<f64>,
|
max_width: Option<f64>,
|
||||||
|
can_gc: CanGc,
|
||||||
) {
|
) {
|
||||||
if !x.is_finite() || !y.is_finite() {
|
if !x.is_finite() || !y.is_finite() {
|
||||||
return;
|
return;
|
||||||
|
@ -1010,7 +1018,11 @@ impl CanvasState {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if self.state.borrow().font_style.is_none() {
|
if self.state.borrow().font_style.is_none() {
|
||||||
self.set_font(canvas, CanvasContextState::DEFAULT_FONT_STYLE.into())
|
self.set_font(
|
||||||
|
canvas,
|
||||||
|
CanvasContextState::DEFAULT_FONT_STYLE.into(),
|
||||||
|
can_gc,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
let is_rtl = match self.state.borrow().direction {
|
let is_rtl = match self.state.borrow().direction {
|
||||||
|
@ -1036,9 +1048,14 @@ impl CanvasState {
|
||||||
global: &GlobalScope,
|
global: &GlobalScope,
|
||||||
canvas: Option<&HTMLCanvasElement>,
|
canvas: Option<&HTMLCanvasElement>,
|
||||||
text: DOMString,
|
text: DOMString,
|
||||||
|
can_gc: CanGc,
|
||||||
) -> DomRoot<TextMetrics> {
|
) -> DomRoot<TextMetrics> {
|
||||||
if self.state.borrow().font_style.is_none() {
|
if self.state.borrow().font_style.is_none() {
|
||||||
self.set_font(canvas, CanvasContextState::DEFAULT_FONT_STYLE.into());
|
self.set_font(
|
||||||
|
canvas,
|
||||||
|
CanvasContextState::DEFAULT_FONT_STYLE.into(),
|
||||||
|
can_gc,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (sender, receiver) = ipc::channel::<CanvasTextMetrics>().unwrap();
|
let (sender, receiver) = ipc::channel::<CanvasTextMetrics>().unwrap();
|
||||||
|
@ -1063,17 +1080,18 @@ impl CanvasState {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-font
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-font
|
||||||
pub fn set_font(&self, canvas: Option<&HTMLCanvasElement>, value: DOMString) {
|
pub fn set_font(&self, canvas: Option<&HTMLCanvasElement>, value: DOMString, can_gc: CanGc) {
|
||||||
let canvas = match canvas {
|
let canvas = match canvas {
|
||||||
Some(element) => element,
|
Some(element) => element,
|
||||||
None => return, // offscreen canvas doesn't have a placeholder canvas
|
None => return, // offscreen canvas doesn't have a placeholder canvas
|
||||||
};
|
};
|
||||||
let node = canvas.upcast::<Node>();
|
let node = canvas.upcast::<Node>();
|
||||||
let window = window_from_node(canvas);
|
let window = window_from_node(canvas);
|
||||||
let resolved_font_style = match window.resolved_font_style_query(node, value.to_string()) {
|
let resolved_font_style =
|
||||||
Some(value) => value,
|
match window.resolved_font_style_query(node, value.to_string(), can_gc) {
|
||||||
None => return, // syntax error
|
Some(value) => value,
|
||||||
};
|
None => return, // syntax error
|
||||||
|
};
|
||||||
self.state.borrow_mut().font_style = Some((*resolved_font_style).clone());
|
self.state.borrow_mut().font_style = Some((*resolved_font_style).clone());
|
||||||
self.send_canvas_2d_msg(Canvas2dMsg::SetFont((*resolved_font_style).clone()));
|
self.send_canvas_2d_msg(Canvas2dMsg::SetFont((*resolved_font_style).clone()));
|
||||||
}
|
}
|
||||||
|
@ -1717,7 +1735,11 @@ impl CanvasState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_color(canvas: Option<&HTMLCanvasElement>, string: &str) -> Result<AbsoluteColor, ()> {
|
pub fn parse_color(
|
||||||
|
canvas: Option<&HTMLCanvasElement>,
|
||||||
|
string: &str,
|
||||||
|
can_gc: CanGc,
|
||||||
|
) -> Result<AbsoluteColor, ()> {
|
||||||
let mut input = ParserInput::new(string);
|
let mut input = ParserInput::new(string);
|
||||||
let mut parser = Parser::new(&mut input);
|
let mut parser = Parser::new(&mut input);
|
||||||
let url = Url::parse("about:blank").unwrap().into();
|
let url = Url::parse("about:blank").unwrap().into();
|
||||||
|
@ -1745,8 +1767,8 @@ pub fn parse_color(canvas: Option<&HTMLCanvasElement>, string: &str) -> Result<A
|
||||||
None => AbsoluteColor::BLACK,
|
None => AbsoluteColor::BLACK,
|
||||||
Some(canvas) => {
|
Some(canvas) => {
|
||||||
let canvas_element = canvas.upcast::<Element>();
|
let canvas_element = canvas.upcast::<Element>();
|
||||||
match canvas_element.style() {
|
match canvas_element.style(can_gc) {
|
||||||
Some(ref s) if canvas_element.has_css_layout_box() => {
|
Some(ref s) if canvas_element.has_css_layout_box(can_gc) => {
|
||||||
s.get_inherited_text().color
|
s.get_inherited_text().color
|
||||||
},
|
},
|
||||||
_ => AbsoluteColor::BLACK,
|
_ => AbsoluteColor::BLACK,
|
||||||
|
|
|
@ -354,7 +354,7 @@ pub fn handle_get_layout(
|
||||||
position: String::from(computed_style.Position()),
|
position: String::from(computed_style.Position()),
|
||||||
z_index: String::from(computed_style.ZIndex()),
|
z_index: String::from(computed_style.ZIndex()),
|
||||||
box_sizing: String::from(computed_style.BoxSizing()),
|
box_sizing: String::from(computed_style.BoxSizing()),
|
||||||
auto_margins: determine_auto_margins(&node),
|
auto_margins: determine_auto_margins(&node, can_gc),
|
||||||
margin_top: String::from(computed_style.MarginTop()),
|
margin_top: String::from(computed_style.MarginTop()),
|
||||||
margin_right: String::from(computed_style.MarginRight()),
|
margin_right: String::from(computed_style.MarginRight()),
|
||||||
margin_bottom: String::from(computed_style.MarginBottom()),
|
margin_bottom: String::from(computed_style.MarginBottom()),
|
||||||
|
@ -373,8 +373,8 @@ pub fn handle_get_layout(
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn determine_auto_margins(node: &Node) -> AutoMargins {
|
fn determine_auto_margins(node: &Node, can_gc: CanGc) -> AutoMargins {
|
||||||
let style = node.style().unwrap();
|
let style = node.style(can_gc).unwrap();
|
||||||
let margin = style.get_margin();
|
let margin = style.get_margin();
|
||||||
AutoMargins {
|
AutoMargins {
|
||||||
top: margin.margin_top.is_auto(),
|
top: margin.margin_top.is_auto(),
|
||||||
|
|
|
@ -37,13 +37,21 @@ pub trait Activatable {
|
||||||
self.as_element().set_active_state(true);
|
self.as_element().set_active_state(true);
|
||||||
|
|
||||||
let win = window_from_node(self.as_element());
|
let win = window_from_node(self.as_element());
|
||||||
win.reflow(ReflowGoal::Full, ReflowReason::ElementStateChanged);
|
win.reflow(
|
||||||
|
ReflowGoal::Full,
|
||||||
|
ReflowReason::ElementStateChanged,
|
||||||
|
CanGc::note(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn exit_formal_activation_state(&self) {
|
fn exit_formal_activation_state(&self) {
|
||||||
self.as_element().set_active_state(false);
|
self.as_element().set_active_state(false);
|
||||||
|
|
||||||
let win = window_from_node(self.as_element());
|
let win = window_from_node(self.as_element());
|
||||||
win.reflow(ReflowGoal::Full, ReflowReason::ElementStateChanged);
|
win.reflow(
|
||||||
|
ReflowGoal::Full,
|
||||||
|
ReflowReason::ElementStateChanged,
|
||||||
|
CanGc::note(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,11 @@ DOMInterfaces = {
|
||||||
},
|
},
|
||||||
|
|
||||||
'CanvasRenderingContext2D': {
|
'CanvasRenderingContext2D': {
|
||||||
'canGc': ['GetTransform','GetImageData', 'CreateImageData', 'CreateImageData_'],
|
'canGc': ['GetTransform','GetImageData', 'CreateImageData', 'CreateImageData_', 'SetFont', 'FillText', 'MeasureText', 'SetStrokeStyle', 'SetFillStyle', 'SetShadowColor'],
|
||||||
|
},
|
||||||
|
|
||||||
|
'CanvasGradient': {
|
||||||
|
'canGc': ['AddColorStop'],
|
||||||
},
|
},
|
||||||
|
|
||||||
'DOMImplementation': {
|
'DOMImplementation': {
|
||||||
|
@ -90,7 +94,7 @@ DOMInterfaces = {
|
||||||
},
|
},
|
||||||
|
|
||||||
'Document': {
|
'Document': {
|
||||||
'canGc': ['Close', 'CreateElement', 'CreateElementNS', 'ImportNode', 'SetTitle', 'Write', 'Writeln', 'CreateEvent', 'CreateRange', 'Open', 'Open_'],
|
'canGc': ['Close', 'CreateElement', 'CreateElementNS', 'ImportNode', 'SetTitle', 'Write', 'Writeln', 'CreateEvent', 'CreateRange', 'Open', 'Open_', 'Fonts', 'ElementFromPoint', 'ElementsFromPoint'],
|
||||||
},
|
},
|
||||||
|
|
||||||
'DynamicModuleOwner': {
|
'DynamicModuleOwner': {
|
||||||
|
@ -98,7 +102,7 @@ DOMInterfaces = {
|
||||||
},
|
},
|
||||||
|
|
||||||
'Element': {
|
'Element': {
|
||||||
'canGc': ['SetInnerHTML', 'SetOuterHTML', 'InsertAdjacentHTML', 'GetClientRects', 'GetBoundingClientRect'],
|
'canGc': ['SetInnerHTML', 'SetOuterHTML', 'InsertAdjacentHTML', 'GetClientRects', 'GetBoundingClientRect', 'SetScrollTop', 'SetScrollLeft', 'Scroll', 'Scroll_', 'ScrollBy', 'ScrollBy_', 'ScrollWidth', 'ScrollHeight', 'ScrollTop', 'ScrollLeft', 'ClientTop', 'ClientLeft', 'ClientWidth', 'ClientHeight'],
|
||||||
},
|
},
|
||||||
|
|
||||||
'ElementInternals': {
|
'ElementInternals': {
|
||||||
|
@ -192,6 +196,14 @@ DOMInterfaces = {
|
||||||
'canGc': ['Content'],
|
'canGc': ['Content'],
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'HTMLElement': {
|
||||||
|
'canGc': ['GetOffsetParent', 'OffsetTop', 'OffsetLeft', 'OffsetWidth', 'OffsetHeight', 'InnerText', 'GetOuterText', 'Focus', 'Blur', 'Click'],
|
||||||
|
},
|
||||||
|
|
||||||
|
'HTMLImageElement': {
|
||||||
|
'canGc': ['Width', 'Height'],
|
||||||
|
},
|
||||||
|
|
||||||
'HTMLTextAreaElement': {
|
'HTMLTextAreaElement': {
|
||||||
'canGc': ['ReportValidity'],
|
'canGc': ['ReportValidity'],
|
||||||
},
|
},
|
||||||
|
@ -213,6 +225,9 @@ DOMInterfaces = {
|
||||||
'canGc': ['GetMetadata'],
|
'canGc': ['GetMetadata'],
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'MouseEvent': {
|
||||||
|
'canGc': ['OffsetX', 'OffsetY'],
|
||||||
|
},
|
||||||
|
|
||||||
'MediaQueryList': {
|
'MediaQueryList': {
|
||||||
'weakReferenceable': True,
|
'weakReferenceable': True,
|
||||||
|
@ -239,11 +254,11 @@ DOMInterfaces = {
|
||||||
},
|
},
|
||||||
|
|
||||||
'OffscreenCanvasRenderingContext2D': {
|
'OffscreenCanvasRenderingContext2D': {
|
||||||
'canGc': ['CreateImageData', 'CreateImageData_', 'GetImageData', 'GetTransform'],
|
'canGc': ['CreateImageData', 'CreateImageData_', 'GetImageData', 'GetTransform', 'SetFont', 'FillText', 'MeasureText', 'SetStrokeStyle', 'SetFillStyle', 'SetShadowColor'],
|
||||||
},
|
},
|
||||||
|
|
||||||
'PaintRenderingContext2D': {
|
'PaintRenderingContext2D': {
|
||||||
'canGc': ['GetTransform'],
|
'canGc': ['GetTransform', 'SetStrokeStyle', 'SetFillStyle', 'SetShadowColor'],
|
||||||
},
|
},
|
||||||
|
|
||||||
'Promise': {
|
'Promise': {
|
||||||
|
@ -272,7 +287,6 @@ DOMInterfaces = {
|
||||||
'canGc': ['Collapse', 'CollapseToEnd', 'CollapseToStart', 'Extend', 'SelectAllChildren', 'SetBaseAndExtent', 'SetPosition'],
|
'canGc': ['Collapse', 'CollapseToEnd', 'CollapseToStart', 'Extend', 'SelectAllChildren', 'SetBaseAndExtent', 'SetPosition'],
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
'ServiceWorkerContainer': {
|
'ServiceWorkerContainer': {
|
||||||
'inRealms': ['Register'],
|
'inRealms': ['Register'],
|
||||||
},
|
},
|
||||||
|
@ -281,6 +295,10 @@ DOMInterfaces = {
|
||||||
'weakReferenceable': True,
|
'weakReferenceable': True,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'ShadowRoot': {
|
||||||
|
'canGc': ['ElementFromPoint', 'ElementsFromPoint'],
|
||||||
|
},
|
||||||
|
|
||||||
'SubtleCrypto': {
|
'SubtleCrypto': {
|
||||||
'inRealms': ['Encrypt', 'Decrypt', 'GenerateKey', 'ImportKey', 'ExportKey']
|
'inRealms': ['Encrypt', 'Decrypt', 'GenerateKey', 'ImportKey', 'ExportKey']
|
||||||
},
|
},
|
||||||
|
@ -305,7 +323,7 @@ DOMInterfaces = {
|
||||||
},
|
},
|
||||||
|
|
||||||
'Window': {
|
'Window': {
|
||||||
'canGc': ['Stop', 'Fetch', 'Open'],
|
'canGc': ['Stop', 'Fetch', 'Scroll', 'Scroll_','ScrollBy', 'ScrollBy_', 'Stop', 'Fetch', 'Open'],
|
||||||
'inRealms': ['Fetch', 'GetOpener'],
|
'inRealms': ['Fetch', 'GetOpener'],
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
|
||||||
use crate::dom::bindings::root::DomRoot;
|
use crate::dom::bindings::root::DomRoot;
|
||||||
use crate::dom::bindings::str::DOMString;
|
use crate::dom::bindings::str::DOMString;
|
||||||
use crate::dom::globalscope::GlobalScope;
|
use crate::dom::globalscope::GlobalScope;
|
||||||
|
use crate::script_runtime::CanGc;
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#canvasgradient
|
// https://html.spec.whatwg.org/multipage/#canvasgradient
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
|
@ -48,12 +49,12 @@ impl CanvasGradient {
|
||||||
|
|
||||||
impl CanvasGradientMethods for CanvasGradient {
|
impl CanvasGradientMethods for CanvasGradient {
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-canvasgradient-addcolorstop
|
// https://html.spec.whatwg.org/multipage/#dom-canvasgradient-addcolorstop
|
||||||
fn AddColorStop(&self, offset: Finite<f64>, color: DOMString) -> ErrorResult {
|
fn AddColorStop(&self, offset: Finite<f64>, color: DOMString, can_gc: CanGc) -> ErrorResult {
|
||||||
if *offset < 0f64 || *offset > 1f64 {
|
if *offset < 0f64 || *offset > 1f64 {
|
||||||
return Err(Error::IndexSize);
|
return Err(Error::IndexSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
let color = match parse_color(None, &color) {
|
let color = match parse_color(None, &color, can_gc) {
|
||||||
Ok(color) => color,
|
Ok(color) => color,
|
||||||
Err(_) => return Err(Error::Syntax),
|
Err(_) => return Err(Error::Syntax),
|
||||||
};
|
};
|
||||||
|
|
|
@ -285,16 +285,16 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-filltext
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-filltext
|
||||||
fn FillText(&self, text: DOMString, x: f64, y: f64, max_width: Option<f64>) {
|
fn FillText(&self, text: DOMString, x: f64, y: f64, max_width: Option<f64>, can_gc: CanGc) {
|
||||||
self.canvas_state
|
self.canvas_state
|
||||||
.fill_text(self.canvas.as_deref(), text, x, y, max_width);
|
.fill_text(self.canvas.as_deref(), text, x, y, max_width, can_gc);
|
||||||
self.mark_as_dirty();
|
self.mark_as_dirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#textmetrics
|
// https://html.spec.whatwg.org/multipage/#textmetrics
|
||||||
fn MeasureText(&self, text: DOMString) -> DomRoot<TextMetrics> {
|
fn MeasureText(&self, text: DOMString, can_gc: CanGc) -> DomRoot<TextMetrics> {
|
||||||
self.canvas_state
|
self.canvas_state
|
||||||
.measure_text(&self.global(), self.canvas.as_deref(), text)
|
.measure_text(&self.global(), self.canvas.as_deref(), text, can_gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-font
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-font
|
||||||
|
@ -303,8 +303,9 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-font
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-font
|
||||||
fn SetFont(&self, value: DOMString) {
|
fn SetFont(&self, value: DOMString, can_gc: CanGc) {
|
||||||
self.canvas_state.set_font(self.canvas.as_deref(), value)
|
self.canvas_state
|
||||||
|
.set_font(self.canvas.as_deref(), value, can_gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-textalign
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-textalign
|
||||||
|
@ -451,9 +452,9 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle
|
||||||
fn SetStrokeStyle(&self, value: StringOrCanvasGradientOrCanvasPattern) {
|
fn SetStrokeStyle(&self, value: StringOrCanvasGradientOrCanvasPattern, can_gc: CanGc) {
|
||||||
self.canvas_state
|
self.canvas_state
|
||||||
.set_stroke_style(self.canvas.as_deref(), value)
|
.set_stroke_style(self.canvas.as_deref(), value, can_gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle
|
||||||
|
@ -462,9 +463,9 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle
|
||||||
fn SetFillStyle(&self, value: StringOrCanvasGradientOrCanvasPattern) {
|
fn SetFillStyle(&self, value: StringOrCanvasGradientOrCanvasPattern, can_gc: CanGc) {
|
||||||
self.canvas_state
|
self.canvas_state
|
||||||
.set_fill_style(self.canvas.as_deref(), value)
|
.set_fill_style(self.canvas.as_deref(), value, can_gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-createimagedata
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-createimagedata
|
||||||
|
@ -656,9 +657,9 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowcolor
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowcolor
|
||||||
fn SetShadowColor(&self, value: DOMString) {
|
fn SetShadowColor(&self, value: DOMString, can_gc: CanGc) {
|
||||||
self.canvas_state
|
self.canvas_state
|
||||||
.set_shadow_color(self.canvas.as_deref(), value)
|
.set_shadow_color(self.canvas.as_deref(), value, can_gc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ use crate::dom::cssrule::CSSRule;
|
||||||
use crate::dom::element::Element;
|
use crate::dom::element::Element;
|
||||||
use crate::dom::node::{document_from_node, stylesheets_owner_from_node, window_from_node, Node};
|
use crate::dom::node::{document_from_node, stylesheets_owner_from_node, window_from_node, Node};
|
||||||
use crate::dom::window::Window;
|
use crate::dom::window::Window;
|
||||||
|
use crate::script_runtime::CanGc;
|
||||||
|
|
||||||
// http://dev.w3.org/csswg/cssom/#the-cssstyledeclaration-interface
|
// http://dev.w3.org/csswg/cssom/#the-cssstyledeclaration-interface
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
|
@ -245,7 +246,7 @@ impl CSSStyleDeclaration {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_computed_style(&self, property: PropertyId) -> DOMString {
|
fn get_computed_style(&self, property: PropertyId, can_gc: CanGc) -> DOMString {
|
||||||
match self.owner {
|
match self.owner {
|
||||||
CSSStyleOwner::CSSRule(..) => {
|
CSSStyleOwner::CSSRule(..) => {
|
||||||
panic!("get_computed_style called on CSSStyleDeclaration with a CSSRule owner")
|
panic!("get_computed_style called on CSSStyleDeclaration with a CSSRule owner")
|
||||||
|
@ -256,7 +257,7 @@ impl CSSStyleDeclaration {
|
||||||
return DOMString::new();
|
return DOMString::new();
|
||||||
}
|
}
|
||||||
let addr = node.to_trusted_node_address();
|
let addr = node.to_trusted_node_address();
|
||||||
window_from_node(node).resolved_style_query(addr, self.pseudo, property)
|
window_from_node(node).resolved_style_query(addr, self.pseudo, property, can_gc)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -264,7 +265,7 @@ impl CSSStyleDeclaration {
|
||||||
fn get_property_value(&self, id: PropertyId) -> DOMString {
|
fn get_property_value(&self, id: PropertyId) -> DOMString {
|
||||||
if self.readonly {
|
if self.readonly {
|
||||||
// Readonly style declarations are used for getComputedStyle.
|
// Readonly style declarations are used for getComputedStyle.
|
||||||
return self.get_computed_style(id);
|
return self.get_computed_style(id, CanGc::note());
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut string = String::new();
|
let mut string = String::new();
|
||||||
|
|
|
@ -694,7 +694,7 @@ impl Document {
|
||||||
self.activity.get() != DocumentActivity::Inactive
|
self.activity.get() != DocumentActivity::Inactive
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_activity(&self, activity: DocumentActivity) {
|
pub fn set_activity(&self, activity: DocumentActivity, can_gc: CanGc) {
|
||||||
// This function should only be called on documents with a browsing context
|
// This function should only be called on documents with a browsing context
|
||||||
assert!(self.has_browsing_context);
|
assert!(self.has_browsing_context);
|
||||||
if activity == self.activity.get() {
|
if activity == self.activity.get() {
|
||||||
|
@ -716,8 +716,11 @@ impl Document {
|
||||||
|
|
||||||
self.title_changed();
|
self.title_changed();
|
||||||
self.dirty_all_nodes();
|
self.dirty_all_nodes();
|
||||||
self.window()
|
self.window().reflow(
|
||||||
.reflow(ReflowGoal::Full, ReflowReason::CachedPageNeededReflow);
|
ReflowGoal::Full,
|
||||||
|
ReflowReason::CachedPageNeededReflow,
|
||||||
|
can_gc,
|
||||||
|
);
|
||||||
self.window().resume();
|
self.window().resume();
|
||||||
media.resume(&client_context_id);
|
media.resume(&client_context_id);
|
||||||
|
|
||||||
|
@ -906,7 +909,7 @@ impl Document {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reflows and disarms the timer if the reflow timer has expired.
|
/// Reflows and disarms the timer if the reflow timer has expired.
|
||||||
pub fn reflow_if_reflow_timer_expired(&self) {
|
pub fn reflow_if_reflow_timer_expired(&self, can_gc: CanGc) {
|
||||||
let Some(reflow_timeout) = self.reflow_timeout.get() else {
|
let Some(reflow_timeout) = self.reflow_timeout.get() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
@ -917,7 +920,7 @@ impl Document {
|
||||||
|
|
||||||
self.reflow_timeout.set(None);
|
self.reflow_timeout.set(None);
|
||||||
self.window
|
self.window
|
||||||
.reflow(ReflowGoal::Full, ReflowReason::RefreshTick);
|
.reflow(ReflowGoal::Full, ReflowReason::RefreshTick, can_gc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Schedules a reflow to be kicked off at the given [`Duration`] in the future. This reflow
|
/// Schedules a reflow to be kicked off at the given [`Duration`] in the future. This reflow
|
||||||
|
@ -1019,11 +1022,11 @@ impl Document {
|
||||||
/// Scroll to the target element, and when we do not find a target
|
/// Scroll to the target element, and when we do not find a target
|
||||||
/// and the fragment is empty or "top", scroll to the top.
|
/// and the fragment is empty or "top", scroll to the top.
|
||||||
/// <https://html.spec.whatwg.org/multipage/#scroll-to-the-fragment-identifier>
|
/// <https://html.spec.whatwg.org/multipage/#scroll-to-the-fragment-identifier>
|
||||||
pub fn check_and_scroll_fragment(&self, fragment: &str) {
|
pub fn check_and_scroll_fragment(&self, fragment: &str, can_gc: CanGc) {
|
||||||
let target = self.find_fragment_node(fragment);
|
let target = self.find_fragment_node(fragment);
|
||||||
|
|
||||||
// Step 1
|
// Step 1
|
||||||
self.set_target_element(target.as_deref());
|
self.set_target_element(target.as_deref(), can_gc);
|
||||||
|
|
||||||
let point = target
|
let point = target
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
@ -1032,7 +1035,9 @@ impl Document {
|
||||||
// inside other scrollable containers. Ideally this should use an implementation of
|
// inside other scrollable containers. Ideally this should use an implementation of
|
||||||
// `scrollIntoView` when that is available:
|
// `scrollIntoView` when that is available:
|
||||||
// See https://github.com/servo/servo/issues/24059.
|
// See https://github.com/servo/servo/issues/24059.
|
||||||
let rect = element.upcast::<Node>().bounding_content_box_or_zero();
|
let rect = element
|
||||||
|
.upcast::<Node>()
|
||||||
|
.bounding_content_box_or_zero(can_gc);
|
||||||
|
|
||||||
// In order to align with element edges, we snap to unscaled pixel boundaries, since
|
// In order to align with element edges, we snap to unscaled pixel boundaries, since
|
||||||
// the paint thread currently does the same for drawing elements. This is important
|
// the paint thread currently does the same for drawing elements. This is important
|
||||||
|
@ -1056,7 +1061,7 @@ impl Document {
|
||||||
|
|
||||||
if let Some((x, y)) = point {
|
if let Some((x, y)) = point {
|
||||||
self.window
|
self.window
|
||||||
.scroll(x as f64, y as f64, ScrollBehavior::Instant)
|
.scroll(x as f64, y as f64, ScrollBehavior::Instant, can_gc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1188,7 +1193,7 @@ impl Document {
|
||||||
|
|
||||||
// Notify the embedder to display an input method.
|
// Notify the embedder to display an input method.
|
||||||
if let Some(kind) = elem.input_method_type() {
|
if let Some(kind) = elem.input_method_type() {
|
||||||
let rect = elem.upcast::<Node>().bounding_content_box_or_zero();
|
let rect = elem.upcast::<Node>().bounding_content_box_or_zero(can_gc);
|
||||||
let rect = Rect::new(
|
let rect = Rect::new(
|
||||||
Point2D::new(rect.origin.x.to_px(), rect.origin.y.to_px()),
|
Point2D::new(rect.origin.x.to_px(), rect.origin.y.to_px()),
|
||||||
Size2D::new(rect.size.width.to_px(), rect.size.height.to_px()),
|
Size2D::new(rect.size.width.to_px(), rect.size.height.to_px()),
|
||||||
|
@ -2088,7 +2093,7 @@ impl Document {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://html.spec.whatwg.org/multipage/#run-the-animation-frame-callbacks>
|
/// <https://html.spec.whatwg.org/multipage/#run-the-animation-frame-callbacks>
|
||||||
pub fn run_the_animation_frame_callbacks(&self) {
|
pub fn run_the_animation_frame_callbacks(&self, can_gc: CanGc) {
|
||||||
rooted_vec!(let mut animation_frame_list);
|
rooted_vec!(let mut animation_frame_list);
|
||||||
mem::swap(
|
mem::swap(
|
||||||
&mut *animation_frame_list,
|
&mut *animation_frame_list,
|
||||||
|
@ -2107,9 +2112,11 @@ impl Document {
|
||||||
|
|
||||||
self.running_animation_callbacks.set(false);
|
self.running_animation_callbacks.set(false);
|
||||||
|
|
||||||
let spurious = !self
|
let spurious = !self.window.reflow(
|
||||||
.window
|
ReflowGoal::Full,
|
||||||
.reflow(ReflowGoal::Full, ReflowReason::RequestAnimationFrame);
|
ReflowReason::RequestAnimationFrame,
|
||||||
|
can_gc,
|
||||||
|
);
|
||||||
|
|
||||||
if spurious && !was_faking_animation_frames {
|
if spurious && !was_faking_animation_frames {
|
||||||
// If the rAF callbacks did not mutate the DOM, then the
|
// If the rAF callbacks did not mutate the DOM, then the
|
||||||
|
@ -2239,7 +2246,7 @@ impl Document {
|
||||||
self.reflow_timeout.set(None);
|
self.reflow_timeout.set(None);
|
||||||
self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage);
|
self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage);
|
||||||
self.window
|
self.window
|
||||||
.reflow(ReflowGoal::Full, ReflowReason::FirstLoad);
|
.reflow(ReflowGoal::Full, ReflowReason::FirstLoad, can_gc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deferred scripts have to wait for page to finish loading,
|
// Deferred scripts have to wait for page to finish loading,
|
||||||
|
@ -2471,7 +2478,7 @@ impl Document {
|
||||||
update_with_current_instant(&document.load_event_end);
|
update_with_current_instant(&document.load_event_end);
|
||||||
|
|
||||||
if let Some(fragment) = document.url().fragment() {
|
if let Some(fragment) = document.url().fragment() {
|
||||||
document.check_and_scroll_fragment(fragment);
|
document.check_and_scroll_fragment(fragment, CanGc::note());
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
self.window.upcast(),
|
self.window.upcast(),
|
||||||
|
@ -3048,12 +3055,14 @@ impl Document {
|
||||||
pub(crate) fn gather_active_resize_observations_at_depth(
|
pub(crate) fn gather_active_resize_observations_at_depth(
|
||||||
&self,
|
&self,
|
||||||
depth: &ResizeObservationDepth,
|
depth: &ResizeObservationDepth,
|
||||||
|
can_gc: CanGc,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let mut has_active_resize_observations = false;
|
let mut has_active_resize_observations = false;
|
||||||
for observer in self.resize_observers.borrow_mut().iter_mut() {
|
for observer in self.resize_observers.borrow_mut().iter_mut() {
|
||||||
observer.gather_active_resize_observations_at_depth(
|
observer.gather_active_resize_observations_at_depth(
|
||||||
depth,
|
depth,
|
||||||
&mut has_active_resize_observations,
|
&mut has_active_resize_observations,
|
||||||
|
can_gc,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
has_active_resize_observations
|
has_active_resize_observations
|
||||||
|
@ -3444,10 +3453,10 @@ impl Document {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// As part of a `update_the_rendering` task, tick all pending animations.
|
/// As part of a `update_the_rendering` task, tick all pending animations.
|
||||||
pub fn tick_all_animations(&self, should_run_rafs: bool) {
|
pub fn tick_all_animations(&self, should_run_rafs: bool, can_gc: CanGc) {
|
||||||
let tick_type = mem::take(&mut *self.pending_animation_ticks.borrow_mut());
|
let tick_type = mem::take(&mut *self.pending_animation_ticks.borrow_mut());
|
||||||
if should_run_rafs {
|
if should_run_rafs {
|
||||||
self.run_the_animation_frame_callbacks();
|
self.run_the_animation_frame_callbacks(can_gc);
|
||||||
}
|
}
|
||||||
if tick_type.contains(AnimationTickType::CSS_ANIMATIONS_AND_TRANSITIONS) {
|
if tick_type.contains(AnimationTickType::CSS_ANIMATIONS_AND_TRANSITIONS) {
|
||||||
self.maybe_mark_animating_nodes_as_dirty();
|
self.maybe_mark_animating_nodes_as_dirty();
|
||||||
|
@ -3839,7 +3848,7 @@ impl Document {
|
||||||
self.referrer_policy.get()
|
self.referrer_policy.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_target_element(&self, node: Option<&Element>) {
|
pub fn set_target_element(&self, node: Option<&Element>, can_gc: CanGc) {
|
||||||
if let Some(ref element) = self.target_element.get() {
|
if let Some(ref element) = self.target_element.get() {
|
||||||
element.set_target_state(false);
|
element.set_target_state(false);
|
||||||
}
|
}
|
||||||
|
@ -3851,7 +3860,7 @@ impl Document {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.window
|
self.window
|
||||||
.reflow(ReflowGoal::Full, ReflowReason::ElementStateChanged);
|
.reflow(ReflowGoal::Full, ReflowReason::ElementStateChanged, can_gc);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn incr_ignore_destructive_writes_counter(&self) {
|
pub fn incr_ignore_destructive_writes_counter(&self) {
|
||||||
|
@ -5280,22 +5289,34 @@ impl DocumentMethods for Document {
|
||||||
);
|
);
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-document-elementfrompoint
|
// https://drafts.csswg.org/cssom-view/#dom-document-elementfrompoint
|
||||||
fn ElementFromPoint(&self, x: Finite<f64>, y: Finite<f64>) -> Option<DomRoot<Element>> {
|
fn ElementFromPoint(
|
||||||
|
&self,
|
||||||
|
x: Finite<f64>,
|
||||||
|
y: Finite<f64>,
|
||||||
|
can_gc: CanGc,
|
||||||
|
) -> Option<DomRoot<Element>> {
|
||||||
self.document_or_shadow_root.element_from_point(
|
self.document_or_shadow_root.element_from_point(
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
self.GetDocumentElement(),
|
self.GetDocumentElement(),
|
||||||
self.has_browsing_context,
|
self.has_browsing_context,
|
||||||
|
can_gc,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-document-elementsfrompoint
|
// https://drafts.csswg.org/cssom-view/#dom-document-elementsfrompoint
|
||||||
fn ElementsFromPoint(&self, x: Finite<f64>, y: Finite<f64>) -> Vec<DomRoot<Element>> {
|
fn ElementsFromPoint(
|
||||||
|
&self,
|
||||||
|
x: Finite<f64>,
|
||||||
|
y: Finite<f64>,
|
||||||
|
can_gc: CanGc,
|
||||||
|
) -> Vec<DomRoot<Element>> {
|
||||||
self.document_or_shadow_root.elements_from_point(
|
self.document_or_shadow_root.elements_from_point(
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
self.GetDocumentElement(),
|
self.GetDocumentElement(),
|
||||||
self.has_browsing_context,
|
self.has_browsing_context,
|
||||||
|
can_gc,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5560,9 +5581,9 @@ impl DocumentMethods for Document {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/css-font-loading/#font-face-source
|
// https://drafts.csswg.org/css-font-loading/#font-face-source
|
||||||
fn Fonts(&self) -> DomRoot<FontFaceSet> {
|
fn Fonts(&self, can_gc: CanGc) -> DomRoot<FontFaceSet> {
|
||||||
self.fonts
|
self.fonts
|
||||||
.or_init(|| FontFaceSet::new(&self.global(), None))
|
.or_init(|| FontFaceSet::new(&self.global(), None, can_gc))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://html.spec.whatwg.org/multipage/#dom-document-hidden>
|
/// <https://html.spec.whatwg.org/multipage/#dom-document-hidden>
|
||||||
|
@ -5625,9 +5646,9 @@ pub struct FakeRequestAnimationFrameCallback {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FakeRequestAnimationFrameCallback {
|
impl FakeRequestAnimationFrameCallback {
|
||||||
pub fn invoke(self) {
|
pub fn invoke(self, can_gc: CanGc) {
|
||||||
let document = self.document.root();
|
let document = self.document.root();
|
||||||
document.run_the_animation_frame_callbacks();
|
document.run_the_animation_frame_callbacks(can_gc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ use crate::dom::element::Element;
|
||||||
use crate::dom::htmlelement::HTMLElement;
|
use crate::dom::htmlelement::HTMLElement;
|
||||||
use crate::dom::node::{self, Node, VecPreOrderInsertionHelper};
|
use crate::dom::node::{self, Node, VecPreOrderInsertionHelper};
|
||||||
use crate::dom::window::Window;
|
use crate::dom::window::Window;
|
||||||
|
use crate::script_runtime::CanGc;
|
||||||
use crate::stylesheet_set::StylesheetSetRef;
|
use crate::stylesheet_set::StylesheetSetRef;
|
||||||
|
|
||||||
#[derive(Clone, JSTraceable, MallocSizeOf)]
|
#[derive(Clone, JSTraceable, MallocSizeOf)]
|
||||||
|
@ -90,8 +91,12 @@ impl DocumentOrShadowRoot {
|
||||||
&self,
|
&self,
|
||||||
client_point: &Point2D<f32>,
|
client_point: &Point2D<f32>,
|
||||||
query_type: NodesFromPointQueryType,
|
query_type: NodesFromPointQueryType,
|
||||||
|
can_gc: CanGc,
|
||||||
) -> Vec<UntrustedNodeAddress> {
|
) -> Vec<UntrustedNodeAddress> {
|
||||||
if !self.window.layout_reflow(QueryMsg::NodesFromPointQuery) {
|
if !self
|
||||||
|
.window
|
||||||
|
.layout_reflow(QueryMsg::NodesFromPointQuery, can_gc)
|
||||||
|
{
|
||||||
return vec![];
|
return vec![];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -108,6 +113,7 @@ impl DocumentOrShadowRoot {
|
||||||
y: Finite<f64>,
|
y: Finite<f64>,
|
||||||
document_element: Option<DomRoot<Element>>,
|
document_element: Option<DomRoot<Element>>,
|
||||||
has_browsing_context: bool,
|
has_browsing_context: bool,
|
||||||
|
can_gc: CanGc,
|
||||||
) -> Option<DomRoot<Element>> {
|
) -> Option<DomRoot<Element>> {
|
||||||
let x = *x as f32;
|
let x = *x as f32;
|
||||||
let y = *y as f32;
|
let y = *y as f32;
|
||||||
|
@ -123,7 +129,7 @@ impl DocumentOrShadowRoot {
|
||||||
}
|
}
|
||||||
|
|
||||||
match self
|
match self
|
||||||
.nodes_from_point(point, NodesFromPointQueryType::Topmost)
|
.nodes_from_point(point, NodesFromPointQueryType::Topmost, can_gc)
|
||||||
.first()
|
.first()
|
||||||
{
|
{
|
||||||
Some(address) => {
|
Some(address) => {
|
||||||
|
@ -147,6 +153,7 @@ impl DocumentOrShadowRoot {
|
||||||
y: Finite<f64>,
|
y: Finite<f64>,
|
||||||
document_element: Option<DomRoot<Element>>,
|
document_element: Option<DomRoot<Element>>,
|
||||||
has_browsing_context: bool,
|
has_browsing_context: bool,
|
||||||
|
can_gc: CanGc,
|
||||||
) -> Vec<DomRoot<Element>> {
|
) -> Vec<DomRoot<Element>> {
|
||||||
let x = *x as f32;
|
let x = *x as f32;
|
||||||
let y = *y as f32;
|
let y = *y as f32;
|
||||||
|
@ -163,7 +170,7 @@ impl DocumentOrShadowRoot {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 1 and Step 3
|
// Step 1 and Step 3
|
||||||
let nodes = self.nodes_from_point(point, NodesFromPointQueryType::All);
|
let nodes = self.nodes_from_point(point, NodesFromPointQueryType::All, can_gc);
|
||||||
let mut elements: Vec<DomRoot<Element>> = nodes
|
let mut elements: Vec<DomRoot<Element>> = nodes
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|&untrusted_node_address| {
|
.flat_map(|&untrusted_node_address| {
|
||||||
|
|
|
@ -423,18 +423,18 @@ impl Element {
|
||||||
|
|
||||||
/// style will be `None` for elements in a `display: none` subtree. otherwise, the element has a
|
/// style will be `None` for elements in a `display: none` subtree. otherwise, the element has a
|
||||||
/// layout box iff it doesn't have `display: none`.
|
/// layout box iff it doesn't have `display: none`.
|
||||||
pub fn style(&self) -> Option<Arc<ComputedValues>> {
|
pub fn style(&self, can_gc: CanGc) -> Option<Arc<ComputedValues>> {
|
||||||
self.upcast::<Node>().style()
|
self.upcast::<Node>().style(can_gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#css-layout-box
|
// https://drafts.csswg.org/cssom-view/#css-layout-box
|
||||||
pub fn has_css_layout_box(&self) -> bool {
|
pub fn has_css_layout_box(&self, can_gc: CanGc) -> bool {
|
||||||
self.style()
|
self.style(can_gc)
|
||||||
.is_some_and(|s| !s.get_box().clone_display().is_none())
|
.is_some_and(|s| !s.get_box().clone_display().is_none())
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#potentially-scrollable
|
// https://drafts.csswg.org/cssom-view/#potentially-scrollable
|
||||||
fn is_potentially_scrollable_body(&self) -> bool {
|
fn is_potentially_scrollable_body(&self, can_gc: CanGc) -> bool {
|
||||||
let node = self.upcast::<Node>();
|
let node = self.upcast::<Node>();
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
node.owner_doc().GetBody().as_deref() == self.downcast::<HTMLElement>(),
|
node.owner_doc().GetBody().as_deref() == self.downcast::<HTMLElement>(),
|
||||||
|
@ -444,14 +444,14 @@ impl Element {
|
||||||
// "An element body (which will be the body element) is potentially
|
// "An element body (which will be the body element) is potentially
|
||||||
// scrollable if all of the following conditions are true:
|
// scrollable if all of the following conditions are true:
|
||||||
// - body has an associated box."
|
// - body has an associated box."
|
||||||
if !self.has_css_layout_box() {
|
if !self.has_css_layout_box(can_gc) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// " - body’s parent element’s computed value of the overflow-x or
|
// " - body’s parent element’s computed value of the overflow-x or
|
||||||
// overflow-y properties is neither visible nor clip."
|
// overflow-y properties is neither visible nor clip."
|
||||||
if let Some(parent) = node.GetParentElement() {
|
if let Some(parent) = node.GetParentElement() {
|
||||||
if let Some(style) = parent.style() {
|
if let Some(style) = parent.style(can_gc) {
|
||||||
if !style.get_box().clone_overflow_x().is_scrollable() &&
|
if !style.get_box().clone_overflow_x().is_scrollable() &&
|
||||||
!style.get_box().clone_overflow_y().is_scrollable()
|
!style.get_box().clone_overflow_y().is_scrollable()
|
||||||
{
|
{
|
||||||
|
@ -462,7 +462,7 @@ impl Element {
|
||||||
|
|
||||||
// " - body’s computed value of the overflow-x or overflow-y properties
|
// " - body’s computed value of the overflow-x or overflow-y properties
|
||||||
// is neither visible nor clip."
|
// is neither visible nor clip."
|
||||||
if let Some(style) = self.style() {
|
if let Some(style) = self.style(can_gc) {
|
||||||
if !style.get_box().clone_overflow_x().is_scrollable() &&
|
if !style.get_box().clone_overflow_x().is_scrollable() &&
|
||||||
!style.get_box().clone_overflow_y().is_scrollable()
|
!style.get_box().clone_overflow_y().is_scrollable()
|
||||||
{
|
{
|
||||||
|
@ -474,17 +474,18 @@ impl Element {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#scrolling-box
|
// https://drafts.csswg.org/cssom-view/#scrolling-box
|
||||||
fn has_scrolling_box(&self) -> bool {
|
fn has_scrolling_box(&self, can_gc: CanGc) -> bool {
|
||||||
// TODO: scrolling mechanism, such as scrollbar (We don't have scrollbar yet)
|
// TODO: scrolling mechanism, such as scrollbar (We don't have scrollbar yet)
|
||||||
// self.has_scrolling_mechanism()
|
// self.has_scrolling_mechanism()
|
||||||
self.style().is_some_and(|style| {
|
self.style(can_gc).is_some_and(|style| {
|
||||||
style.get_box().clone_overflow_x().is_scrollable() ||
|
style.get_box().clone_overflow_x().is_scrollable() ||
|
||||||
style.get_box().clone_overflow_y().is_scrollable()
|
style.get_box().clone_overflow_y().is_scrollable()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has_overflow(&self) -> bool {
|
fn has_overflow(&self, can_gc: CanGc) -> bool {
|
||||||
self.ScrollHeight() > self.ClientHeight() || self.ScrollWidth() > self.ClientWidth()
|
self.ScrollHeight(can_gc) > self.ClientHeight(can_gc) ||
|
||||||
|
self.ScrollWidth(can_gc) > self.ClientWidth(can_gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shadow_root(&self) -> Option<DomRoot<ShadowRoot>> {
|
fn shadow_root(&self) -> Option<DomRoot<ShadowRoot>> {
|
||||||
|
@ -1835,7 +1836,7 @@ impl Element {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-element-scroll
|
// https://drafts.csswg.org/cssom-view/#dom-element-scroll
|
||||||
pub fn scroll(&self, x_: f64, y_: f64, behavior: ScrollBehavior) {
|
pub fn scroll(&self, x_: f64, y_: f64, behavior: ScrollBehavior, can_gc: CanGc) {
|
||||||
// Step 1.2 or 2.3
|
// Step 1.2 or 2.3
|
||||||
let x = if x_.is_finite() { x_ } else { 0.0f64 };
|
let x = if x_.is_finite() { x_ } else { 0.0f64 };
|
||||||
let y = if y_.is_finite() { y_ } else { 0.0f64 };
|
let y = if y_.is_finite() { y_ } else { 0.0f64 };
|
||||||
|
@ -1859,7 +1860,7 @@ impl Element {
|
||||||
// Step 7
|
// Step 7
|
||||||
if *self.root_element() == *self {
|
if *self.root_element() == *self {
|
||||||
if doc.quirks_mode() != QuirksMode::Quirks {
|
if doc.quirks_mode() != QuirksMode::Quirks {
|
||||||
win.scroll(x, y, behavior);
|
win.scroll(x, y, behavior, can_gc);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -1868,19 +1869,22 @@ impl Element {
|
||||||
// Step 9
|
// Step 9
|
||||||
if doc.GetBody().as_deref() == self.downcast::<HTMLElement>() &&
|
if doc.GetBody().as_deref() == self.downcast::<HTMLElement>() &&
|
||||||
doc.quirks_mode() == QuirksMode::Quirks &&
|
doc.quirks_mode() == QuirksMode::Quirks &&
|
||||||
!self.is_potentially_scrollable_body()
|
!self.is_potentially_scrollable_body(can_gc)
|
||||||
{
|
{
|
||||||
win.scroll(x, y, behavior);
|
win.scroll(x, y, behavior, can_gc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 10
|
// Step 10
|
||||||
if !self.has_css_layout_box() || !self.has_scrolling_box() || !self.has_overflow() {
|
if !self.has_css_layout_box(can_gc) ||
|
||||||
|
!self.has_scrolling_box(can_gc) ||
|
||||||
|
!self.has_overflow(can_gc)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 11
|
// Step 11
|
||||||
win.scroll_node(node, x, y, behavior);
|
win.scroll_node(node, x, y, behavior, can_gc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://w3c.github.io/DOM-Parsing/#parsing
|
// https://w3c.github.io/DOM-Parsing/#parsing
|
||||||
|
@ -2343,7 +2347,7 @@ impl ElementMethods for Element {
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-element-getclientrects
|
// https://drafts.csswg.org/cssom-view/#dom-element-getclientrects
|
||||||
fn GetClientRects(&self, can_gc: CanGc) -> Vec<DomRoot<DOMRect>> {
|
fn GetClientRects(&self, can_gc: CanGc) -> Vec<DomRoot<DOMRect>> {
|
||||||
let win = window_from_node(self);
|
let win = window_from_node(self);
|
||||||
let raw_rects = self.upcast::<Node>().content_boxes();
|
let raw_rects = self.upcast::<Node>().content_boxes(can_gc);
|
||||||
raw_rects
|
raw_rects
|
||||||
.iter()
|
.iter()
|
||||||
.map(|rect| {
|
.map(|rect| {
|
||||||
|
@ -2362,7 +2366,7 @@ impl ElementMethods for Element {
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-element-getboundingclientrect
|
// https://drafts.csswg.org/cssom-view/#dom-element-getboundingclientrect
|
||||||
fn GetBoundingClientRect(&self, can_gc: CanGc) -> DomRoot<DOMRect> {
|
fn GetBoundingClientRect(&self, can_gc: CanGc) -> DomRoot<DOMRect> {
|
||||||
let win = window_from_node(self);
|
let win = window_from_node(self);
|
||||||
let rect = self.upcast::<Node>().bounding_content_box_or_zero();
|
let rect = self.upcast::<Node>().bounding_content_box_or_zero(can_gc);
|
||||||
DOMRect::new(
|
DOMRect::new(
|
||||||
win.upcast(),
|
win.upcast(),
|
||||||
rect.origin.x.to_f64_px(),
|
rect.origin.x.to_f64_px(),
|
||||||
|
@ -2374,47 +2378,52 @@ impl ElementMethods for Element {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-element-scroll
|
// https://drafts.csswg.org/cssom-view/#dom-element-scroll
|
||||||
fn Scroll(&self, options: &ScrollToOptions) {
|
fn Scroll(&self, options: &ScrollToOptions, can_gc: CanGc) {
|
||||||
// Step 1
|
// Step 1
|
||||||
let left = options.left.unwrap_or(self.ScrollLeft());
|
let left = options.left.unwrap_or(self.ScrollLeft(can_gc));
|
||||||
let top = options.top.unwrap_or(self.ScrollTop());
|
let top = options.top.unwrap_or(self.ScrollTop(can_gc));
|
||||||
self.scroll(left, top, options.parent.behavior);
|
self.scroll(left, top, options.parent.behavior, can_gc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-element-scroll
|
// https://drafts.csswg.org/cssom-view/#dom-element-scroll
|
||||||
fn Scroll_(&self, x: f64, y: f64) {
|
fn Scroll_(&self, x: f64, y: f64, can_gc: CanGc) {
|
||||||
self.scroll(x, y, ScrollBehavior::Auto);
|
self.scroll(x, y, ScrollBehavior::Auto, can_gc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-element-scrollto
|
// https://drafts.csswg.org/cssom-view/#dom-element-scrollto
|
||||||
fn ScrollTo(&self, options: &ScrollToOptions) {
|
fn ScrollTo(&self, options: &ScrollToOptions) {
|
||||||
self.Scroll(options);
|
self.Scroll(options, CanGc::note());
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-element-scrollto
|
// https://drafts.csswg.org/cssom-view/#dom-element-scrollto
|
||||||
fn ScrollTo_(&self, x: f64, y: f64) {
|
fn ScrollTo_(&self, x: f64, y: f64) {
|
||||||
self.Scroll_(x, y);
|
self.Scroll_(x, y, CanGc::note());
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-element-scrollby
|
// https://drafts.csswg.org/cssom-view/#dom-element-scrollby
|
||||||
fn ScrollBy(&self, options: &ScrollToOptions) {
|
fn ScrollBy(&self, options: &ScrollToOptions, can_gc: CanGc) {
|
||||||
// Step 2
|
// Step 2
|
||||||
let delta_left = options.left.unwrap_or(0.0f64);
|
let delta_left = options.left.unwrap_or(0.0f64);
|
||||||
let delta_top = options.top.unwrap_or(0.0f64);
|
let delta_top = options.top.unwrap_or(0.0f64);
|
||||||
let left = self.ScrollLeft();
|
let left = self.ScrollLeft(can_gc);
|
||||||
let top = self.ScrollTop();
|
let top = self.ScrollTop(can_gc);
|
||||||
self.scroll(left + delta_left, top + delta_top, options.parent.behavior);
|
self.scroll(
|
||||||
|
left + delta_left,
|
||||||
|
top + delta_top,
|
||||||
|
options.parent.behavior,
|
||||||
|
can_gc,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-element-scrollby
|
// https://drafts.csswg.org/cssom-view/#dom-element-scrollby
|
||||||
fn ScrollBy_(&self, x: f64, y: f64) {
|
fn ScrollBy_(&self, x: f64, y: f64, can_gc: CanGc) {
|
||||||
let left = self.ScrollLeft();
|
let left = self.ScrollLeft(can_gc);
|
||||||
let top = self.ScrollTop();
|
let top = self.ScrollTop(can_gc);
|
||||||
self.scroll(left + x, top + y, ScrollBehavior::Auto);
|
self.scroll(left + x, top + y, ScrollBehavior::Auto, can_gc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-element-scrolltop
|
// https://drafts.csswg.org/cssom-view/#dom-element-scrolltop
|
||||||
fn ScrollTop(&self) -> f64 {
|
fn ScrollTop(&self, can_gc: CanGc) -> f64 {
|
||||||
let node = self.upcast::<Node>();
|
let node = self.upcast::<Node>();
|
||||||
|
|
||||||
// Step 1
|
// Step 1
|
||||||
|
@ -2444,13 +2453,13 @@ impl ElementMethods for Element {
|
||||||
// Step 7
|
// Step 7
|
||||||
if doc.GetBody().as_deref() == self.downcast::<HTMLElement>() &&
|
if doc.GetBody().as_deref() == self.downcast::<HTMLElement>() &&
|
||||||
doc.quirks_mode() == QuirksMode::Quirks &&
|
doc.quirks_mode() == QuirksMode::Quirks &&
|
||||||
!self.is_potentially_scrollable_body()
|
!self.is_potentially_scrollable_body(can_gc)
|
||||||
{
|
{
|
||||||
return win.ScrollY() as f64;
|
return win.ScrollY() as f64;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 8
|
// Step 8
|
||||||
if !self.has_css_layout_box() {
|
if !self.has_css_layout_box(can_gc) {
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2460,7 +2469,7 @@ impl ElementMethods for Element {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-element-scrolltop
|
// https://drafts.csswg.org/cssom-view/#dom-element-scrolltop
|
||||||
fn SetScrollTop(&self, y_: f64) {
|
fn SetScrollTop(&self, y_: f64, can_gc: CanGc) {
|
||||||
let behavior = ScrollBehavior::Auto;
|
let behavior = ScrollBehavior::Auto;
|
||||||
|
|
||||||
// Step 1, 2
|
// Step 1, 2
|
||||||
|
@ -2485,7 +2494,7 @@ impl ElementMethods for Element {
|
||||||
// Step 7
|
// Step 7
|
||||||
if *self.root_element() == *self {
|
if *self.root_element() == *self {
|
||||||
if doc.quirks_mode() != QuirksMode::Quirks {
|
if doc.quirks_mode() != QuirksMode::Quirks {
|
||||||
win.scroll(win.ScrollX() as f64, y, behavior);
|
win.scroll(win.ScrollX() as f64, y, behavior, can_gc);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -2494,23 +2503,26 @@ impl ElementMethods for Element {
|
||||||
// Step 9
|
// Step 9
|
||||||
if doc.GetBody().as_deref() == self.downcast::<HTMLElement>() &&
|
if doc.GetBody().as_deref() == self.downcast::<HTMLElement>() &&
|
||||||
doc.quirks_mode() == QuirksMode::Quirks &&
|
doc.quirks_mode() == QuirksMode::Quirks &&
|
||||||
!self.is_potentially_scrollable_body()
|
!self.is_potentially_scrollable_body(can_gc)
|
||||||
{
|
{
|
||||||
win.scroll(win.ScrollX() as f64, y, behavior);
|
win.scroll(win.ScrollX() as f64, y, behavior, can_gc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 10
|
// Step 10
|
||||||
if !self.has_css_layout_box() || !self.has_scrolling_box() || !self.has_overflow() {
|
if !self.has_css_layout_box(can_gc) ||
|
||||||
|
!self.has_scrolling_box(can_gc) ||
|
||||||
|
!self.has_overflow(can_gc)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 11
|
// Step 11
|
||||||
win.scroll_node(node, self.ScrollLeft(), y, behavior);
|
win.scroll_node(node, self.ScrollLeft(can_gc), y, behavior, can_gc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-element-scrolltop
|
// https://drafts.csswg.org/cssom-view/#dom-element-scrolltop
|
||||||
fn ScrollLeft(&self) -> f64 {
|
fn ScrollLeft(&self, can_gc: CanGc) -> f64 {
|
||||||
let node = self.upcast::<Node>();
|
let node = self.upcast::<Node>();
|
||||||
|
|
||||||
// Step 1
|
// Step 1
|
||||||
|
@ -2540,13 +2552,13 @@ impl ElementMethods for Element {
|
||||||
// Step 7
|
// Step 7
|
||||||
if doc.GetBody().as_deref() == self.downcast::<HTMLElement>() &&
|
if doc.GetBody().as_deref() == self.downcast::<HTMLElement>() &&
|
||||||
doc.quirks_mode() == QuirksMode::Quirks &&
|
doc.quirks_mode() == QuirksMode::Quirks &&
|
||||||
!self.is_potentially_scrollable_body()
|
!self.is_potentially_scrollable_body(can_gc)
|
||||||
{
|
{
|
||||||
return win.ScrollX() as f64;
|
return win.ScrollX() as f64;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 8
|
// Step 8
|
||||||
if !self.has_css_layout_box() {
|
if !self.has_css_layout_box(can_gc) {
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2556,7 +2568,7 @@ impl ElementMethods for Element {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-element-scrollleft
|
// https://drafts.csswg.org/cssom-view/#dom-element-scrollleft
|
||||||
fn SetScrollLeft(&self, x_: f64) {
|
fn SetScrollLeft(&self, x_: f64, can_gc: CanGc) {
|
||||||
let behavior = ScrollBehavior::Auto;
|
let behavior = ScrollBehavior::Auto;
|
||||||
|
|
||||||
// Step 1, 2
|
// Step 1, 2
|
||||||
|
@ -2584,56 +2596,59 @@ impl ElementMethods for Element {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
win.scroll(x, win.ScrollY() as f64, behavior);
|
win.scroll(x, win.ScrollY() as f64, behavior, can_gc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 9
|
// Step 9
|
||||||
if doc.GetBody().as_deref() == self.downcast::<HTMLElement>() &&
|
if doc.GetBody().as_deref() == self.downcast::<HTMLElement>() &&
|
||||||
doc.quirks_mode() == QuirksMode::Quirks &&
|
doc.quirks_mode() == QuirksMode::Quirks &&
|
||||||
!self.is_potentially_scrollable_body()
|
!self.is_potentially_scrollable_body(can_gc)
|
||||||
{
|
{
|
||||||
win.scroll(x, win.ScrollY() as f64, behavior);
|
win.scroll(x, win.ScrollY() as f64, behavior, can_gc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 10
|
// Step 10
|
||||||
if !self.has_css_layout_box() || !self.has_scrolling_box() || !self.has_overflow() {
|
if !self.has_css_layout_box(can_gc) ||
|
||||||
|
!self.has_scrolling_box(can_gc) ||
|
||||||
|
!self.has_overflow(can_gc)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 11
|
// Step 11
|
||||||
win.scroll_node(node, x, self.ScrollTop(), behavior);
|
win.scroll_node(node, x, self.ScrollTop(can_gc), behavior, can_gc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-element-scrollwidth
|
// https://drafts.csswg.org/cssom-view/#dom-element-scrollwidth
|
||||||
fn ScrollWidth(&self) -> i32 {
|
fn ScrollWidth(&self, can_gc: CanGc) -> i32 {
|
||||||
self.upcast::<Node>().scroll_area().size.width
|
self.upcast::<Node>().scroll_area(can_gc).size.width
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-element-scrollheight
|
// https://drafts.csswg.org/cssom-view/#dom-element-scrollheight
|
||||||
fn ScrollHeight(&self) -> i32 {
|
fn ScrollHeight(&self, can_gc: CanGc) -> i32 {
|
||||||
self.upcast::<Node>().scroll_area().size.height
|
self.upcast::<Node>().scroll_area(can_gc).size.height
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-element-clienttop
|
// https://drafts.csswg.org/cssom-view/#dom-element-clienttop
|
||||||
fn ClientTop(&self) -> i32 {
|
fn ClientTop(&self, can_gc: CanGc) -> i32 {
|
||||||
self.client_rect().origin.y
|
self.client_rect(can_gc).origin.y
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-element-clientleft
|
// https://drafts.csswg.org/cssom-view/#dom-element-clientleft
|
||||||
fn ClientLeft(&self) -> i32 {
|
fn ClientLeft(&self, can_gc: CanGc) -> i32 {
|
||||||
self.client_rect().origin.x
|
self.client_rect(can_gc).origin.x
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-element-clientwidth
|
// https://drafts.csswg.org/cssom-view/#dom-element-clientwidth
|
||||||
fn ClientWidth(&self) -> i32 {
|
fn ClientWidth(&self, can_gc: CanGc) -> i32 {
|
||||||
self.client_rect().size.width
|
self.client_rect(can_gc).size.width
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-element-clientheight
|
// https://drafts.csswg.org/cssom-view/#dom-element-clientheight
|
||||||
fn ClientHeight(&self) -> i32 {
|
fn ClientHeight(&self, can_gc: CanGc) -> i32 {
|
||||||
self.client_rect().size.height
|
self.client_rect(can_gc).size.height
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://w3c.github.io/DOM-Parsing/#widl-Element-innerHTML>
|
/// <https://w3c.github.io/DOM-Parsing/#widl-Element-innerHTML>
|
||||||
|
@ -3850,7 +3865,7 @@ impl SelectorsElement for DomRoot<Element> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Element {
|
impl Element {
|
||||||
fn client_rect(&self) -> Rect<i32> {
|
fn client_rect(&self, can_gc: CanGc) -> Rect<i32> {
|
||||||
let doc = self.node.owner_doc();
|
let doc = self.node.owner_doc();
|
||||||
|
|
||||||
if let Some(rect) = self
|
if let Some(rect) = self
|
||||||
|
@ -3867,7 +3882,7 @@ impl Element {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut rect = self.upcast::<Node>().client_rect();
|
let mut rect = self.upcast::<Node>().client_rect(can_gc);
|
||||||
let in_quirks_mode = doc.quirks_mode() == QuirksMode::Quirks;
|
let in_quirks_mode = doc.quirks_mode() == QuirksMode::Quirks;
|
||||||
|
|
||||||
if (in_quirks_mode && doc.GetBody().as_deref() == self.downcast::<HTMLElement>()) ||
|
if (in_quirks_mode && doc.GetBody().as_deref() == self.downcast::<HTMLElement>()) ||
|
||||||
|
@ -4329,9 +4344,11 @@ impl TaskOnce for ElementPerformFullscreenEnter {
|
||||||
// Step 7.5
|
// Step 7.5
|
||||||
element.set_fullscreen_state(true);
|
element.set_fullscreen_state(true);
|
||||||
document.set_fullscreen_element(Some(&element));
|
document.set_fullscreen_element(Some(&element));
|
||||||
document
|
document.window().reflow(
|
||||||
.window()
|
ReflowGoal::Full,
|
||||||
.reflow(ReflowGoal::Full, ReflowReason::ElementStateChanged);
|
ReflowReason::ElementStateChanged,
|
||||||
|
CanGc::note(),
|
||||||
|
);
|
||||||
|
|
||||||
// Step 7.6
|
// Step 7.6
|
||||||
document
|
document
|
||||||
|
@ -4366,9 +4383,11 @@ impl TaskOnce for ElementPerformFullscreenExit {
|
||||||
// Step 9.6
|
// Step 9.6
|
||||||
element.set_fullscreen_state(false);
|
element.set_fullscreen_state(false);
|
||||||
|
|
||||||
document
|
document.window().reflow(
|
||||||
.window()
|
ReflowGoal::Full,
|
||||||
.reflow(ReflowGoal::Full, ReflowReason::ElementStateChanged);
|
ReflowReason::ElementStateChanged,
|
||||||
|
CanGc::note(),
|
||||||
|
);
|
||||||
|
|
||||||
document.set_fullscreen_element(None);
|
document.set_fullscreen_element(None);
|
||||||
|
|
||||||
|
|
|
@ -31,12 +31,12 @@ impl FontFaceSet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(global: &GlobalScope, proto: Option<HandleObject>) -> DomRoot<Self> {
|
pub fn new(global: &GlobalScope, proto: Option<HandleObject>, can_gc: CanGc) -> DomRoot<Self> {
|
||||||
reflect_dom_object_with_proto(
|
reflect_dom_object_with_proto(
|
||||||
Box::new(FontFaceSet::new_inherited(global)),
|
Box::new(FontFaceSet::new_inherited(global)),
|
||||||
global,
|
global,
|
||||||
proto,
|
proto,
|
||||||
CanGc::note(),
|
can_gc,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -94,7 +94,7 @@ impl History {
|
||||||
|
|
||||||
// Step 8
|
// Step 8
|
||||||
if let Some(fragment) = url.fragment() {
|
if let Some(fragment) = url.fragment() {
|
||||||
document.check_and_scroll_fragment(fragment);
|
document.check_and_scroll_fragment(fragment, can_gc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 11
|
// Step 11
|
||||||
|
|
|
@ -604,7 +604,7 @@ impl Activatable for HTMLAnchorElement {
|
||||||
if let Some(element) = target.downcast::<Element>() {
|
if let Some(element) = target.downcast::<Element>() {
|
||||||
if target.is::<HTMLImageElement>() && element.has_attribute(&local_name!("ismap")) {
|
if target.is::<HTMLImageElement>() && element.has_attribute(&local_name!("ismap")) {
|
||||||
let target_node = element.upcast::<Node>();
|
let target_node = element.upcast::<Node>();
|
||||||
let rect = target_node.bounding_content_box_or_zero();
|
let rect = target_node.bounding_content_box_or_zero(CanGc::note());
|
||||||
ismap_suffix = Some(format!(
|
ismap_suffix = Some(format!(
|
||||||
"?{},{}",
|
"?{},{}",
|
||||||
mouse_event.ClientX().to_f32().unwrap() - rect.origin.x.to_f32_px(),
|
mouse_event.ClientX().to_f32().unwrap() - rect.origin.x.to_f32_px(),
|
||||||
|
|
0
components/script/dom/htmlbuttonelement.rs
Executable file → Normal file
0
components/script/dom/htmlbuttonelement.rs
Executable file → Normal file
|
@ -113,18 +113,18 @@ impl HTMLElement {
|
||||||
/// `.outerText` in JavaScript.`
|
/// `.outerText` in JavaScript.`
|
||||||
///
|
///
|
||||||
/// <https://html.spec.whatwg.org/multipage/#get-the-text-steps>
|
/// <https://html.spec.whatwg.org/multipage/#get-the-text-steps>
|
||||||
fn get_inner_outer_text(&self) -> DOMString {
|
fn get_inner_outer_text(&self, can_gc: CanGc) -> DOMString {
|
||||||
let node = self.upcast::<Node>();
|
let node = self.upcast::<Node>();
|
||||||
let window = window_from_node(node);
|
let window = window_from_node(node);
|
||||||
let element = self.as_element();
|
let element = self.as_element();
|
||||||
|
|
||||||
// Step 1.
|
// Step 1.
|
||||||
let element_not_rendered = !node.is_connected() || !element.has_css_layout_box();
|
let element_not_rendered = !node.is_connected() || !element.has_css_layout_box(can_gc);
|
||||||
if element_not_rendered {
|
if element_not_rendered {
|
||||||
return node.GetTextContent().unwrap();
|
return node.GetTextContent().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
window.layout_reflow(QueryMsg::ElementInnerOuterTextQuery);
|
window.layout_reflow(QueryMsg::ElementInnerOuterTextQuery, can_gc);
|
||||||
let text = window
|
let text = window
|
||||||
.layout()
|
.layout()
|
||||||
.query_element_inner_outer_text(node.to_trusted_node_address());
|
.query_element_inner_outer_text(node.to_trusted_node_address());
|
||||||
|
@ -419,65 +419,65 @@ impl HTMLElementMethods for HTMLElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-htmlelement-offsetparent
|
// https://drafts.csswg.org/cssom-view/#dom-htmlelement-offsetparent
|
||||||
fn GetOffsetParent(&self) -> Option<DomRoot<Element>> {
|
fn GetOffsetParent(&self, can_gc: CanGc) -> Option<DomRoot<Element>> {
|
||||||
if self.is::<HTMLBodyElement>() || self.is::<HTMLHtmlElement>() {
|
if self.is::<HTMLBodyElement>() || self.is::<HTMLHtmlElement>() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let node = self.upcast::<Node>();
|
let node = self.upcast::<Node>();
|
||||||
let window = window_from_node(self);
|
let window = window_from_node(self);
|
||||||
let (element, _) = window.offset_parent_query(node);
|
let (element, _) = window.offset_parent_query(node, can_gc);
|
||||||
|
|
||||||
element
|
element
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-htmlelement-offsettop
|
// https://drafts.csswg.org/cssom-view/#dom-htmlelement-offsettop
|
||||||
fn OffsetTop(&self) -> i32 {
|
fn OffsetTop(&self, can_gc: CanGc) -> i32 {
|
||||||
if self.is::<HTMLBodyElement>() {
|
if self.is::<HTMLBodyElement>() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
let node = self.upcast::<Node>();
|
let node = self.upcast::<Node>();
|
||||||
let window = window_from_node(self);
|
let window = window_from_node(self);
|
||||||
let (_, rect) = window.offset_parent_query(node);
|
let (_, rect) = window.offset_parent_query(node, can_gc);
|
||||||
|
|
||||||
rect.origin.y.to_nearest_px()
|
rect.origin.y.to_nearest_px()
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-htmlelement-offsetleft
|
// https://drafts.csswg.org/cssom-view/#dom-htmlelement-offsetleft
|
||||||
fn OffsetLeft(&self) -> i32 {
|
fn OffsetLeft(&self, can_gc: CanGc) -> i32 {
|
||||||
if self.is::<HTMLBodyElement>() {
|
if self.is::<HTMLBodyElement>() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
let node = self.upcast::<Node>();
|
let node = self.upcast::<Node>();
|
||||||
let window = window_from_node(self);
|
let window = window_from_node(self);
|
||||||
let (_, rect) = window.offset_parent_query(node);
|
let (_, rect) = window.offset_parent_query(node, can_gc);
|
||||||
|
|
||||||
rect.origin.x.to_nearest_px()
|
rect.origin.x.to_nearest_px()
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-htmlelement-offsetwidth
|
// https://drafts.csswg.org/cssom-view/#dom-htmlelement-offsetwidth
|
||||||
fn OffsetWidth(&self) -> i32 {
|
fn OffsetWidth(&self, can_gc: CanGc) -> i32 {
|
||||||
let node = self.upcast::<Node>();
|
let node = self.upcast::<Node>();
|
||||||
let window = window_from_node(self);
|
let window = window_from_node(self);
|
||||||
let (_, rect) = window.offset_parent_query(node);
|
let (_, rect) = window.offset_parent_query(node, can_gc);
|
||||||
|
|
||||||
rect.size.width.to_nearest_px()
|
rect.size.width.to_nearest_px()
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-htmlelement-offsetheight
|
// https://drafts.csswg.org/cssom-view/#dom-htmlelement-offsetheight
|
||||||
fn OffsetHeight(&self) -> i32 {
|
fn OffsetHeight(&self, can_gc: CanGc) -> i32 {
|
||||||
let node = self.upcast::<Node>();
|
let node = self.upcast::<Node>();
|
||||||
let window = window_from_node(self);
|
let window = window_from_node(self);
|
||||||
let (_, rect) = window.offset_parent_query(node);
|
let (_, rect) = window.offset_parent_query(node, can_gc);
|
||||||
|
|
||||||
rect.size.height.to_nearest_px()
|
rect.size.height.to_nearest_px()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://html.spec.whatwg.org/multipage/#the-innertext-idl-attribute>
|
/// <https://html.spec.whatwg.org/multipage/#the-innertext-idl-attribute>
|
||||||
fn InnerText(&self) -> DOMString {
|
fn InnerText(&self, can_gc: CanGc) -> DOMString {
|
||||||
self.get_inner_outer_text()
|
self.get_inner_outer_text(can_gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://html.spec.whatwg.org/multipage/#set-the-inner-text-steps>
|
/// <https://html.spec.whatwg.org/multipage/#set-the-inner-text-steps>
|
||||||
|
@ -491,8 +491,8 @@ impl HTMLElementMethods for HTMLElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://html.spec.whatwg.org/multipage/#dom-outertext>
|
/// <https://html.spec.whatwg.org/multipage/#dom-outertext>
|
||||||
fn GetOuterText(&self) -> Fallible<DOMString> {
|
fn GetOuterText(&self, can_gc: CanGc) -> Fallible<DOMString> {
|
||||||
Ok(self.get_inner_outer_text())
|
Ok(self.get_inner_outer_text(can_gc))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://html.spec.whatwg.org/multipage/#the-innertext-idl-attribute:dom-outertext-2>
|
/// <https://html.spec.whatwg.org/multipage/#the-innertext-idl-attribute:dom-outertext-2>
|
||||||
|
|
|
@ -193,7 +193,7 @@ impl HTMLIFrameElement {
|
||||||
|
|
||||||
let window_size = WindowSizeData {
|
let window_size = WindowSizeData {
|
||||||
initial_viewport: window
|
initial_viewport: window
|
||||||
.inner_window_dimensions_query(browsing_context_id)
|
.inner_window_dimensions_query(browsing_context_id, can_gc)
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
device_pixel_ratio: window.device_pixel_ratio(),
|
device_pixel_ratio: window.device_pixel_ratio(),
|
||||||
};
|
};
|
||||||
|
|
|
@ -1596,9 +1596,9 @@ impl HTMLImageElementMethods for HTMLImageElement {
|
||||||
make_bool_setter!(SetIsMap, "ismap");
|
make_bool_setter!(SetIsMap, "ismap");
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-img-width
|
// https://html.spec.whatwg.org/multipage/#dom-img-width
|
||||||
fn Width(&self) -> u32 {
|
fn Width(&self, can_gc: CanGc) -> u32 {
|
||||||
let node = self.upcast::<Node>();
|
let node = self.upcast::<Node>();
|
||||||
match node.bounding_content_box() {
|
match node.bounding_content_box(can_gc) {
|
||||||
Some(rect) => rect.size.width.to_px() as u32,
|
Some(rect) => rect.size.width.to_px() as u32,
|
||||||
None => self.NaturalWidth(),
|
None => self.NaturalWidth(),
|
||||||
}
|
}
|
||||||
|
@ -1610,9 +1610,9 @@ impl HTMLImageElementMethods for HTMLImageElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-img-height
|
// https://html.spec.whatwg.org/multipage/#dom-img-height
|
||||||
fn Height(&self) -> u32 {
|
fn Height(&self, can_gc: CanGc) -> u32 {
|
||||||
let node = self.upcast::<Node>();
|
let node = self.upcast::<Node>();
|
||||||
match node.bounding_content_box() {
|
match node.bounding_content_box(can_gc) {
|
||||||
Some(rect) => rect.size.height.to_px() as u32,
|
Some(rect) => rect.size.height.to_px() as u32,
|
||||||
None => self.NaturalHeight(),
|
None => self.NaturalHeight(),
|
||||||
}
|
}
|
||||||
|
|
6
components/script/dom/htmlinputelement.rs
Executable file → Normal file
6
components/script/dom/htmlinputelement.rs
Executable file → Normal file
|
@ -2517,7 +2517,11 @@ impl VirtualMethods for HTMLInputElement {
|
||||||
// now.
|
// now.
|
||||||
if let Some(point_in_target) = mouse_event.point_in_target() {
|
if let Some(point_in_target) = mouse_event.point_in_target() {
|
||||||
let window = window_from_node(self);
|
let window = window_from_node(self);
|
||||||
let index = window.text_index_query(self.upcast::<Node>(), point_in_target);
|
let index = window.text_index_query(
|
||||||
|
self.upcast::<Node>(),
|
||||||
|
point_in_target,
|
||||||
|
CanGc::note(),
|
||||||
|
);
|
||||||
if let Some(i) = index {
|
if let Some(i) = index {
|
||||||
self.textinput.borrow_mut().set_edit_point_index(i);
|
self.textinput.borrow_mut().set_edit_point_index(i);
|
||||||
// trigger redraw
|
// trigger redraw
|
||||||
|
|
0
components/script/dom/htmlobjectelement.rs
Executable file → Normal file
0
components/script/dom/htmlobjectelement.rs
Executable file → Normal file
0
components/script/dom/htmlselectelement.rs
Executable file → Normal file
0
components/script/dom/htmlselectelement.rs
Executable file → Normal file
0
components/script/dom/htmltextareaelement.rs
Executable file → Normal file
0
components/script/dom/htmltextareaelement.rs
Executable file → Normal file
|
@ -276,13 +276,13 @@ impl MouseEventMethods for MouseEvent {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-mouseevent-offsetx
|
// https://drafts.csswg.org/cssom-view/#dom-mouseevent-offsetx
|
||||||
fn OffsetX(&self) -> i32 {
|
fn OffsetX(&self, can_gc: CanGc) -> i32 {
|
||||||
let event = self.upcast::<Event>();
|
let event = self.upcast::<Event>();
|
||||||
if event.dispatching() {
|
if event.dispatching() {
|
||||||
match event.GetTarget() {
|
match event.GetTarget() {
|
||||||
Some(target) => {
|
Some(target) => {
|
||||||
if let Some(node) = target.downcast::<Node>() {
|
if let Some(node) = target.downcast::<Node>() {
|
||||||
let rect = node.client_rect();
|
let rect = node.client_rect(can_gc);
|
||||||
self.client_x.get() - rect.origin.x
|
self.client_x.get() - rect.origin.x
|
||||||
} else {
|
} else {
|
||||||
self.offset_x.get()
|
self.offset_x.get()
|
||||||
|
@ -296,13 +296,13 @@ impl MouseEventMethods for MouseEvent {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-mouseevent-offsety
|
// https://drafts.csswg.org/cssom-view/#dom-mouseevent-offsety
|
||||||
fn OffsetY(&self) -> i32 {
|
fn OffsetY(&self, can_gc: CanGc) -> i32 {
|
||||||
let event = self.upcast::<Event>();
|
let event = self.upcast::<Event>();
|
||||||
if event.dispatching() {
|
if event.dispatching() {
|
||||||
match event.GetTarget() {
|
match event.GetTarget() {
|
||||||
Some(target) => {
|
Some(target) => {
|
||||||
if let Some(node) = target.downcast::<Node>() {
|
if let Some(node) = target.downcast::<Node>() {
|
||||||
let rect = node.client_rect();
|
let rect = node.client_rect(can_gc);
|
||||||
self.client_y.get() - rect.origin.y
|
self.client_y.get() - rect.origin.y
|
||||||
} else {
|
} else {
|
||||||
self.offset_y.get()
|
self.offset_y.get()
|
||||||
|
|
|
@ -793,25 +793,25 @@ impl Node {
|
||||||
|
|
||||||
/// Returns the rendered bounding content box if the element is rendered,
|
/// Returns the rendered bounding content box if the element is rendered,
|
||||||
/// and none otherwise.
|
/// and none otherwise.
|
||||||
pub fn bounding_content_box(&self) -> Option<Rect<Au>> {
|
pub fn bounding_content_box(&self, can_gc: CanGc) -> Option<Rect<Au>> {
|
||||||
window_from_node(self).content_box_query(self)
|
window_from_node(self).content_box_query(self, can_gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bounding_content_box_or_zero(&self) -> Rect<Au> {
|
pub fn bounding_content_box_or_zero(&self, can_gc: CanGc) -> Rect<Au> {
|
||||||
self.bounding_content_box().unwrap_or_else(Rect::zero)
|
self.bounding_content_box(can_gc).unwrap_or_else(Rect::zero)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn content_boxes(&self) -> Vec<Rect<Au>> {
|
pub fn content_boxes(&self, can_gc: CanGc) -> Vec<Rect<Au>> {
|
||||||
window_from_node(self).content_boxes_query(self)
|
window_from_node(self).content_boxes_query(self, can_gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn client_rect(&self) -> Rect<i32> {
|
pub fn client_rect(&self, can_gc: CanGc) -> Rect<i32> {
|
||||||
window_from_node(self).client_rect_query(self)
|
window_from_node(self).client_rect_query(self, can_gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://drafts.csswg.org/cssom-view/#dom-element-scrollwidth>
|
/// <https://drafts.csswg.org/cssom-view/#dom-element-scrollwidth>
|
||||||
/// <https://drafts.csswg.org/cssom-view/#dom-element-scrollheight>
|
/// <https://drafts.csswg.org/cssom-view/#dom-element-scrollheight>
|
||||||
pub fn scroll_area(&self) -> Rect<i32> {
|
pub fn scroll_area(&self, can_gc: CanGc) -> Rect<i32> {
|
||||||
// "1. Let document be the element’s node document.""
|
// "1. Let document be the element’s node document.""
|
||||||
let document = self.owner_doc();
|
let document = self.owner_doc();
|
||||||
|
|
||||||
|
@ -837,7 +837,7 @@ impl Node {
|
||||||
// element is not potentially scrollable, return max(viewport scrolling area
|
// element is not potentially scrollable, return max(viewport scrolling area
|
||||||
// width, viewport width)."
|
// width, viewport width)."
|
||||||
if (is_root && !in_quirks_mode) || (is_body_element && in_quirks_mode) {
|
if (is_root && !in_quirks_mode) || (is_body_element && in_quirks_mode) {
|
||||||
let viewport_scrolling_area = window.scrolling_area_query(None);
|
let viewport_scrolling_area = window.scrolling_area_query(None, can_gc);
|
||||||
return Rect::new(
|
return Rect::new(
|
||||||
viewport_scrolling_area.origin,
|
viewport_scrolling_area.origin,
|
||||||
viewport_scrolling_area.size.max(viewport),
|
viewport_scrolling_area.size.max(viewport),
|
||||||
|
@ -847,7 +847,7 @@ impl Node {
|
||||||
// "6. If the element does not have any associated box return zero and terminate
|
// "6. If the element does not have any associated box return zero and terminate
|
||||||
// these steps."
|
// these steps."
|
||||||
// "7. Return the width of the element’s scrolling area."
|
// "7. Return the width of the element’s scrolling area."
|
||||||
window.scrolling_area_query(Some(self))
|
window.scrolling_area_query(Some(self), can_gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scroll_offset(&self) -> Vector2D<f32> {
|
pub fn scroll_offset(&self) -> Vector2D<f32> {
|
||||||
|
@ -1270,8 +1270,8 @@ impl Node {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn style(&self) -> Option<Arc<ComputedValues>> {
|
pub fn style(&self, can_gc: CanGc) -> Option<Arc<ComputedValues>> {
|
||||||
if !window_from_node(self).layout_reflow(QueryMsg::StyleQuery) {
|
if !window_from_node(self).layout_reflow(QueryMsg::StyleQuery, can_gc) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
self.style_data
|
self.style_data
|
||||||
|
|
|
@ -140,9 +140,9 @@ impl OffscreenCanvasRenderingContext2DMethods for OffscreenCanvasRenderingContex
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowcolor
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowcolor
|
||||||
fn SetShadowColor(&self, value: DOMString) {
|
fn SetShadowColor(&self, value: DOMString, can_gc: CanGc) {
|
||||||
self.canvas_state
|
self.canvas_state
|
||||||
.set_shadow_color(self.htmlcanvas.as_deref(), value)
|
.set_shadow_color(self.htmlcanvas.as_deref(), value, can_gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle
|
||||||
|
@ -151,9 +151,9 @@ impl OffscreenCanvasRenderingContext2DMethods for OffscreenCanvasRenderingContex
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle
|
||||||
fn SetStrokeStyle(&self, value: StringOrCanvasGradientOrCanvasPattern) {
|
fn SetStrokeStyle(&self, value: StringOrCanvasGradientOrCanvasPattern, can_gc: CanGc) {
|
||||||
self.canvas_state
|
self.canvas_state
|
||||||
.set_stroke_style(self.htmlcanvas.as_deref(), value)
|
.set_stroke_style(self.htmlcanvas.as_deref(), value, can_gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle
|
||||||
|
@ -162,9 +162,9 @@ impl OffscreenCanvasRenderingContext2DMethods for OffscreenCanvasRenderingContex
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle
|
||||||
fn SetFillStyle(&self, value: StringOrCanvasGradientOrCanvasPattern) {
|
fn SetFillStyle(&self, value: StringOrCanvasGradientOrCanvasPattern, can_gc: CanGc) {
|
||||||
self.canvas_state
|
self.canvas_state
|
||||||
.set_fill_style(self.htmlcanvas.as_deref(), value)
|
.set_fill_style(self.htmlcanvas.as_deref(), value, can_gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-createlineargradient
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-createlineargradient
|
||||||
|
@ -250,15 +250,15 @@ impl OffscreenCanvasRenderingContext2DMethods for OffscreenCanvasRenderingContex
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-filltext
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-filltext
|
||||||
fn FillText(&self, text: DOMString, x: f64, y: f64, max_width: Option<f64>) {
|
fn FillText(&self, text: DOMString, x: f64, y: f64, max_width: Option<f64>, can_gc: CanGc) {
|
||||||
self.canvas_state
|
self.canvas_state
|
||||||
.fill_text(self.htmlcanvas.as_deref(), text, x, y, max_width)
|
.fill_text(self.htmlcanvas.as_deref(), text, x, y, max_width, can_gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#textmetrics
|
// https://html.spec.whatwg.org/multipage/#textmetrics
|
||||||
fn MeasureText(&self, text: DOMString) -> DomRoot<TextMetrics> {
|
fn MeasureText(&self, text: DOMString, can_gc: CanGc) -> DomRoot<TextMetrics> {
|
||||||
self.canvas_state
|
self.canvas_state
|
||||||
.measure_text(&self.global(), self.htmlcanvas.as_deref(), text)
|
.measure_text(&self.global(), self.htmlcanvas.as_deref(), text, can_gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-font
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-font
|
||||||
|
@ -267,9 +267,9 @@ impl OffscreenCanvasRenderingContext2DMethods for OffscreenCanvasRenderingContex
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-font
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-font
|
||||||
fn SetFont(&self, value: DOMString) {
|
fn SetFont(&self, value: DOMString, can_gc: CanGc) {
|
||||||
self.canvas_state
|
self.canvas_state
|
||||||
.set_font(self.htmlcanvas.as_deref(), value)
|
.set_font(self.htmlcanvas.as_deref(), value, can_gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-textalign
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-textalign
|
||||||
|
|
|
@ -304,8 +304,8 @@ impl PaintRenderingContext2DMethods for PaintRenderingContext2D {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle
|
||||||
fn SetStrokeStyle(&self, value: StringOrCanvasGradientOrCanvasPattern) {
|
fn SetStrokeStyle(&self, value: StringOrCanvasGradientOrCanvasPattern, can_gc: CanGc) {
|
||||||
self.context.SetStrokeStyle(value)
|
self.context.SetStrokeStyle(value, can_gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle
|
||||||
|
@ -314,8 +314,8 @@ impl PaintRenderingContext2DMethods for PaintRenderingContext2D {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle
|
||||||
fn SetFillStyle(&self, value: StringOrCanvasGradientOrCanvasPattern) {
|
fn SetFillStyle(&self, value: StringOrCanvasGradientOrCanvasPattern, can_gc: CanGc) {
|
||||||
self.context.SetFillStyle(value)
|
self.context.SetFillStyle(value, can_gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-createlineargradient
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-createlineargradient
|
||||||
|
@ -427,7 +427,7 @@ impl PaintRenderingContext2DMethods for PaintRenderingContext2D {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowcolor
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowcolor
|
||||||
fn SetShadowColor(&self, value: DOMString) {
|
fn SetShadowColor(&self, value: DOMString, can_gc: CanGc) {
|
||||||
self.context.SetShadowColor(value)
|
self.context.SetShadowColor(value, can_gc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,10 +75,11 @@ impl ResizeObserver {
|
||||||
&self,
|
&self,
|
||||||
depth: &ResizeObservationDepth,
|
depth: &ResizeObservationDepth,
|
||||||
has_active: &mut bool,
|
has_active: &mut bool,
|
||||||
|
can_gc: CanGc,
|
||||||
) {
|
) {
|
||||||
for (observation, target) in self.observation_targets.borrow_mut().iter_mut() {
|
for (observation, target) in self.observation_targets.borrow_mut().iter_mut() {
|
||||||
observation.state = Default::default();
|
observation.state = Default::default();
|
||||||
if let Some(size) = observation.is_active(target) {
|
if let Some(size) = observation.is_active(target, can_gc) {
|
||||||
let target_depth = calculate_depth_for_node(target);
|
let target_depth = calculate_depth_for_node(target);
|
||||||
if target_depth > *depth {
|
if target_depth > *depth {
|
||||||
observation.state = ObservationState::Active(size).into();
|
observation.state = ObservationState::Active(size).into();
|
||||||
|
@ -251,9 +252,9 @@ impl ResizeObservation {
|
||||||
/// <https://drafts.csswg.org/resize-observer/#dom-resizeobservation-isactive>
|
/// <https://drafts.csswg.org/resize-observer/#dom-resizeobservation-isactive>
|
||||||
/// Returning an optional calculated size, instead of a boolean,
|
/// Returning an optional calculated size, instead of a boolean,
|
||||||
/// to avoid recalculating the size in the subsequent broadcast.
|
/// to avoid recalculating the size in the subsequent broadcast.
|
||||||
fn is_active(&self, target: &Element) -> Option<Rect<Au>> {
|
fn is_active(&self, target: &Element, can_gc: CanGc) -> Option<Rect<Au>> {
|
||||||
let last_reported_size = self.last_reported_sizes.borrow()[0];
|
let last_reported_size = self.last_reported_sizes.borrow()[0];
|
||||||
let box_size = calculate_box_size(target, &self.observed_box.borrow());
|
let box_size = calculate_box_size(target, &self.observed_box.borrow(), can_gc);
|
||||||
let is_active = box_size.width().to_f64_px() != last_reported_size.inline_size() ||
|
let is_active = box_size.width().to_f64_px() != last_reported_size.inline_size() ||
|
||||||
box_size.height().to_f64_px() != last_reported_size.block_size();
|
box_size.height().to_f64_px() != last_reported_size.block_size();
|
||||||
if is_active {
|
if is_active {
|
||||||
|
@ -272,14 +273,18 @@ fn calculate_depth_for_node(target: &Element) -> ResizeObservationDepth {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://drafts.csswg.org/resize-observer/#calculate-box-size>
|
/// <https://drafts.csswg.org/resize-observer/#calculate-box-size>
|
||||||
fn calculate_box_size(target: &Element, observed_box: &ResizeObserverBoxOptions) -> Rect<Au> {
|
fn calculate_box_size(
|
||||||
|
target: &Element,
|
||||||
|
observed_box: &ResizeObserverBoxOptions,
|
||||||
|
can_gc: CanGc,
|
||||||
|
) -> Rect<Au> {
|
||||||
match observed_box {
|
match observed_box {
|
||||||
ResizeObserverBoxOptions::Content_box => {
|
ResizeObserverBoxOptions::Content_box => {
|
||||||
// Note: only taking first fragment,
|
// Note: only taking first fragment,
|
||||||
// but the spec will expand to cover all fragments.
|
// but the spec will expand to cover all fragments.
|
||||||
target
|
target
|
||||||
.upcast::<Node>()
|
.upcast::<Node>()
|
||||||
.content_boxes()
|
.content_boxes(can_gc)
|
||||||
.pop()
|
.pop()
|
||||||
.unwrap_or_else(Rect::zero)
|
.unwrap_or_else(Rect::zero)
|
||||||
},
|
},
|
||||||
|
|
|
@ -588,7 +588,7 @@ impl ServoParser {
|
||||||
assert!(!self.suspended.get());
|
assert!(!self.suspended.get());
|
||||||
assert!(!self.aborted.get());
|
assert!(!self.aborted.get());
|
||||||
|
|
||||||
self.document.reflow_if_reflow_timer_expired();
|
self.document.reflow_if_reflow_timer_expired(can_gc);
|
||||||
let script = match feed(&self.tokenizer) {
|
let script = match feed(&self.tokenizer) {
|
||||||
TokenizerResult::Done => return,
|
TokenizerResult::Done => return,
|
||||||
TokenizerResult::Script(script) => script,
|
TokenizerResult::Script(script) => script,
|
||||||
|
|
|
@ -26,6 +26,7 @@ use crate::dom::element::Element;
|
||||||
use crate::dom::node::{Node, NodeDamage, NodeFlags, ShadowIncluding, UnbindContext};
|
use crate::dom::node::{Node, NodeDamage, NodeFlags, ShadowIncluding, UnbindContext};
|
||||||
use crate::dom::stylesheetlist::{StyleSheetList, StyleSheetListOwner};
|
use crate::dom::stylesheetlist::{StyleSheetList, StyleSheetListOwner};
|
||||||
use crate::dom::window::Window;
|
use crate::dom::window::Window;
|
||||||
|
use crate::script_runtime::CanGc;
|
||||||
use crate::stylesheet_set::StylesheetSetRef;
|
use crate::stylesheet_set::StylesheetSetRef;
|
||||||
|
|
||||||
/// Whether a shadow root hosts an User Agent widget.
|
/// Whether a shadow root hosts an User Agent widget.
|
||||||
|
@ -177,7 +178,12 @@ impl ShadowRootMethods for ShadowRoot {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-document-elementfrompoint
|
// https://drafts.csswg.org/cssom-view/#dom-document-elementfrompoint
|
||||||
fn ElementFromPoint(&self, x: Finite<f64>, y: Finite<f64>) -> Option<DomRoot<Element>> {
|
fn ElementFromPoint(
|
||||||
|
&self,
|
||||||
|
x: Finite<f64>,
|
||||||
|
y: Finite<f64>,
|
||||||
|
can_gc: CanGc,
|
||||||
|
) -> Option<DomRoot<Element>> {
|
||||||
// Return the result of running the retargeting algorithm with context object
|
// Return the result of running the retargeting algorithm with context object
|
||||||
// and the original result as input.
|
// and the original result as input.
|
||||||
match self.document_or_shadow_root.element_from_point(
|
match self.document_or_shadow_root.element_from_point(
|
||||||
|
@ -185,6 +191,7 @@ impl ShadowRootMethods for ShadowRoot {
|
||||||
y,
|
y,
|
||||||
None,
|
None,
|
||||||
self.document.has_browsing_context(),
|
self.document.has_browsing_context(),
|
||||||
|
can_gc,
|
||||||
) {
|
) {
|
||||||
Some(e) => {
|
Some(e) => {
|
||||||
let retargeted_node = self.upcast::<Node>().retarget(e.upcast::<Node>());
|
let retargeted_node = self.upcast::<Node>().retarget(e.upcast::<Node>());
|
||||||
|
@ -195,13 +202,18 @@ impl ShadowRootMethods for ShadowRoot {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-document-elementsfrompoint
|
// https://drafts.csswg.org/cssom-view/#dom-document-elementsfrompoint
|
||||||
fn ElementsFromPoint(&self, x: Finite<f64>, y: Finite<f64>) -> Vec<DomRoot<Element>> {
|
fn ElementsFromPoint(
|
||||||
|
&self,
|
||||||
|
x: Finite<f64>,
|
||||||
|
y: Finite<f64>,
|
||||||
|
can_gc: CanGc,
|
||||||
|
) -> Vec<DomRoot<Element>> {
|
||||||
// Return the result of running the retargeting algorithm with context object
|
// Return the result of running the retargeting algorithm with context object
|
||||||
// and the original result as input
|
// and the original result as input
|
||||||
let mut elements = Vec::new();
|
let mut elements = Vec::new();
|
||||||
for e in self
|
for e in self
|
||||||
.document_or_shadow_root
|
.document_or_shadow_root
|
||||||
.elements_from_point(x, y, None, self.document.has_browsing_context())
|
.elements_from_point(x, y, None, self.document.has_browsing_context(), can_gc)
|
||||||
.iter()
|
.iter()
|
||||||
{
|
{
|
||||||
let retargeted_node = self.upcast::<Node>().retarget(e.upcast::<Node>());
|
let retargeted_node = self.upcast::<Node>().retarget(e.upcast::<Node>());
|
||||||
|
|
|
@ -1196,46 +1196,46 @@ impl WindowMethods for Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-window-scroll
|
// https://drafts.csswg.org/cssom-view/#dom-window-scroll
|
||||||
fn Scroll(&self, options: &ScrollToOptions) {
|
fn Scroll(&self, options: &ScrollToOptions, can_gc: CanGc) {
|
||||||
// Step 1
|
// Step 1
|
||||||
let left = options.left.unwrap_or(0.0f64);
|
let left = options.left.unwrap_or(0.0f64);
|
||||||
let top = options.top.unwrap_or(0.0f64);
|
let top = options.top.unwrap_or(0.0f64);
|
||||||
self.scroll(left, top, options.parent.behavior);
|
self.scroll(left, top, options.parent.behavior, can_gc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-window-scroll
|
// https://drafts.csswg.org/cssom-view/#dom-window-scroll
|
||||||
fn Scroll_(&self, x: f64, y: f64) {
|
fn Scroll_(&self, x: f64, y: f64, can_gc: CanGc) {
|
||||||
self.scroll(x, y, ScrollBehavior::Auto);
|
self.scroll(x, y, ScrollBehavior::Auto, can_gc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-window-scrollto
|
// https://drafts.csswg.org/cssom-view/#dom-window-scrollto
|
||||||
fn ScrollTo(&self, options: &ScrollToOptions) {
|
fn ScrollTo(&self, options: &ScrollToOptions) {
|
||||||
self.Scroll(options);
|
self.Scroll(options, CanGc::note());
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-window-scrollto
|
// https://drafts.csswg.org/cssom-view/#dom-window-scrollto
|
||||||
fn ScrollTo_(&self, x: f64, y: f64) {
|
fn ScrollTo_(&self, x: f64, y: f64) {
|
||||||
self.scroll(x, y, ScrollBehavior::Auto);
|
self.scroll(x, y, ScrollBehavior::Auto, CanGc::note());
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-window-scrollby
|
// https://drafts.csswg.org/cssom-view/#dom-window-scrollby
|
||||||
fn ScrollBy(&self, options: &ScrollToOptions) {
|
fn ScrollBy(&self, options: &ScrollToOptions, can_gc: CanGc) {
|
||||||
// Step 1
|
// Step 1
|
||||||
let x = options.left.unwrap_or(0.0f64);
|
let x = options.left.unwrap_or(0.0f64);
|
||||||
let y = options.top.unwrap_or(0.0f64);
|
let y = options.top.unwrap_or(0.0f64);
|
||||||
self.ScrollBy_(x, y);
|
self.ScrollBy_(x, y, can_gc);
|
||||||
self.scroll(x, y, options.parent.behavior);
|
self.scroll(x, y, options.parent.behavior, can_gc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-window-scrollby
|
// https://drafts.csswg.org/cssom-view/#dom-window-scrollby
|
||||||
fn ScrollBy_(&self, x: f64, y: f64) {
|
fn ScrollBy_(&self, x: f64, y: f64, can_gc: CanGc) {
|
||||||
// Step 3
|
// Step 3
|
||||||
let left = x + self.ScrollX() as f64;
|
let left = x + self.ScrollX() as f64;
|
||||||
// Step 4
|
// Step 4
|
||||||
let top = y + self.ScrollY() as f64;
|
let top = y + self.ScrollY() as f64;
|
||||||
|
|
||||||
// Step 5
|
// Step 5
|
||||||
self.scroll(left, top, ScrollBehavior::Auto);
|
self.scroll(left, top, ScrollBehavior::Auto, can_gc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#dom-window-resizeto
|
// https://drafts.csswg.org/cssom-view/#dom-window-resizeto
|
||||||
|
@ -1700,7 +1700,7 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://drafts.csswg.org/cssom-view/#dom-window-scroll>
|
/// <https://drafts.csswg.org/cssom-view/#dom-window-scroll>
|
||||||
pub fn scroll(&self, x_: f64, y_: f64, behavior: ScrollBehavior) {
|
pub fn scroll(&self, x_: f64, y_: f64, behavior: ScrollBehavior, can_gc: CanGc) {
|
||||||
// Step 3
|
// Step 3
|
||||||
let xfinite = if x_.is_finite() { x_ } else { 0.0f64 };
|
let xfinite = if x_.is_finite() { x_ } else { 0.0f64 };
|
||||||
let yfinite = if y_.is_finite() { y_ } else { 0.0f64 };
|
let yfinite = if y_.is_finite() { y_ } else { 0.0f64 };
|
||||||
|
@ -1713,7 +1713,7 @@ impl Window {
|
||||||
|
|
||||||
// Step 7 & 8
|
// Step 7 & 8
|
||||||
// TODO: Consider `block-end` and `inline-end` overflow direction.
|
// TODO: Consider `block-end` and `inline-end` overflow direction.
|
||||||
let scrolling_area = self.scrolling_area_query(None);
|
let scrolling_area = self.scrolling_area_query(None, can_gc);
|
||||||
let x = xfinite
|
let x = xfinite
|
||||||
.min(scrolling_area.width() as f64 - viewport.width as f64)
|
.min(scrolling_area.width() as f64 - viewport.width as f64)
|
||||||
.max(0.0f64);
|
.max(0.0f64);
|
||||||
|
@ -1739,6 +1739,7 @@ impl Window {
|
||||||
self.upcast::<GlobalScope>().pipeline_id().root_scroll_id(),
|
self.upcast::<GlobalScope>().pipeline_id().root_scroll_id(),
|
||||||
behavior,
|
behavior,
|
||||||
None,
|
None,
|
||||||
|
can_gc,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1750,6 +1751,7 @@ impl Window {
|
||||||
scroll_id: ExternalScrollId,
|
scroll_id: ExternalScrollId,
|
||||||
_behavior: ScrollBehavior,
|
_behavior: ScrollBehavior,
|
||||||
_element: Option<&Element>,
|
_element: Option<&Element>,
|
||||||
|
can_gc: CanGc,
|
||||||
) {
|
) {
|
||||||
// TODO Step 1
|
// TODO Step 1
|
||||||
// TODO(mrobinson, #18709): Add smooth scrolling support to WebRender so that we can
|
// TODO(mrobinson, #18709): Add smooth scrolling support to WebRender so that we can
|
||||||
|
@ -1760,6 +1762,7 @@ impl Window {
|
||||||
scroll_offset: Vector2D::new(-x, -y),
|
scroll_offset: Vector2D::new(-x, -y),
|
||||||
}),
|
}),
|
||||||
ReflowReason::ScrollFromScript,
|
ReflowReason::ScrollFromScript,
|
||||||
|
can_gc,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1960,7 +1963,7 @@ impl Window {
|
||||||
/// that layout might hold if the first layout hasn't happened yet (which
|
/// that layout might hold if the first layout hasn't happened yet (which
|
||||||
/// may happen in the only case a query reflow may bail out, that is, if the
|
/// may happen in the only case a query reflow may bail out, that is, if the
|
||||||
/// viewport size is not present). See #11223 for an example of that.
|
/// viewport size is not present). See #11223 for an example of that.
|
||||||
pub fn reflow(&self, reflow_goal: ReflowGoal, reason: ReflowReason) -> bool {
|
pub fn reflow(&self, reflow_goal: ReflowGoal, reason: ReflowReason, can_gc: CanGc) -> bool {
|
||||||
// Fetch the pending web fonts before layout, in case a font loads during
|
// Fetch the pending web fonts before layout, in case a font loads during
|
||||||
// the layout.
|
// the layout.
|
||||||
let pending_web_fonts = self.layout.borrow().waiting_for_web_fonts_to_load();
|
let pending_web_fonts = self.layout.borrow().waiting_for_web_fonts_to_load();
|
||||||
|
@ -1994,7 +1997,7 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
let document = self.Document();
|
let document = self.Document();
|
||||||
let font_face_set = document.Fonts();
|
let font_face_set = document.Fonts(can_gc);
|
||||||
let is_ready_state_complete = document.ReadyState() == DocumentReadyState::Complete;
|
let is_ready_state_complete = document.ReadyState() == DocumentReadyState::Complete;
|
||||||
|
|
||||||
// From https://drafts.csswg.org/css-font-loading/#font-face-set-ready:
|
// From https://drafts.csswg.org/css-font-loading/#font-face-set-ready:
|
||||||
|
@ -2069,12 +2072,21 @@ impl Window {
|
||||||
receiver.recv().unwrap();
|
receiver.recv().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn layout_reflow(&self, query_msg: QueryMsg) -> bool {
|
pub fn layout_reflow(&self, query_msg: QueryMsg, can_gc: CanGc) -> bool {
|
||||||
self.reflow(ReflowGoal::LayoutQuery(query_msg), ReflowReason::Query)
|
self.reflow(
|
||||||
|
ReflowGoal::LayoutQuery(query_msg),
|
||||||
|
ReflowReason::Query,
|
||||||
|
can_gc,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolved_font_style_query(&self, node: &Node, value: String) -> Option<ServoArc<Font>> {
|
pub fn resolved_font_style_query(
|
||||||
if !self.layout_reflow(QueryMsg::ResolvedFontStyleQuery) {
|
&self,
|
||||||
|
node: &Node,
|
||||||
|
value: String,
|
||||||
|
can_gc: CanGc,
|
||||||
|
) -> Option<ServoArc<Font>> {
|
||||||
|
if !self.layout_reflow(QueryMsg::ResolvedFontStyleQuery, can_gc) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2088,22 +2100,22 @@ impl Window {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn content_box_query(&self, node: &Node) -> Option<UntypedRect<Au>> {
|
pub fn content_box_query(&self, node: &Node, can_gc: CanGc) -> Option<UntypedRect<Au>> {
|
||||||
if !self.layout_reflow(QueryMsg::ContentBox) {
|
if !self.layout_reflow(QueryMsg::ContentBox, can_gc) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
self.layout.borrow().query_content_box(node.to_opaque())
|
self.layout.borrow().query_content_box(node.to_opaque())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn content_boxes_query(&self, node: &Node) -> Vec<UntypedRect<Au>> {
|
pub fn content_boxes_query(&self, node: &Node, can_gc: CanGc) -> Vec<UntypedRect<Au>> {
|
||||||
if !self.layout_reflow(QueryMsg::ContentBoxes) {
|
if !self.layout_reflow(QueryMsg::ContentBoxes, can_gc) {
|
||||||
return vec![];
|
return vec![];
|
||||||
}
|
}
|
||||||
self.layout.borrow().query_content_boxes(node.to_opaque())
|
self.layout.borrow().query_content_boxes(node.to_opaque())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn client_rect_query(&self, node: &Node) -> UntypedRect<i32> {
|
pub fn client_rect_query(&self, node: &Node, can_gc: CanGc) -> UntypedRect<i32> {
|
||||||
if !self.layout_reflow(QueryMsg::ClientRectQuery) {
|
if !self.layout_reflow(QueryMsg::ClientRectQuery, can_gc) {
|
||||||
return Rect::zero();
|
return Rect::zero();
|
||||||
}
|
}
|
||||||
self.layout.borrow().query_client_rect(node.to_opaque())
|
self.layout.borrow().query_client_rect(node.to_opaque())
|
||||||
|
@ -2111,9 +2123,9 @@ impl Window {
|
||||||
|
|
||||||
/// Find the scroll area of the given node, if it is not None. If the node
|
/// Find the scroll area of the given node, if it is not None. If the node
|
||||||
/// is None, find the scroll area of the viewport.
|
/// is None, find the scroll area of the viewport.
|
||||||
pub fn scrolling_area_query(&self, node: Option<&Node>) -> UntypedRect<i32> {
|
pub fn scrolling_area_query(&self, node: Option<&Node>, can_gc: CanGc) -> UntypedRect<i32> {
|
||||||
let opaque = node.map(|node| node.to_opaque());
|
let opaque = node.map(|node| node.to_opaque());
|
||||||
if !self.layout_reflow(QueryMsg::ScrollingAreaQuery) {
|
if !self.layout_reflow(QueryMsg::ScrollingAreaQuery, can_gc) {
|
||||||
return Rect::zero();
|
return Rect::zero();
|
||||||
}
|
}
|
||||||
self.layout.borrow().query_scrolling_area(opaque)
|
self.layout.borrow().query_scrolling_area(opaque)
|
||||||
|
@ -2127,7 +2139,14 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/cssom-view/#element-scrolling-members
|
// https://drafts.csswg.org/cssom-view/#element-scrolling-members
|
||||||
pub fn scroll_node(&self, node: &Node, x_: f64, y_: f64, behavior: ScrollBehavior) {
|
pub fn scroll_node(
|
||||||
|
&self,
|
||||||
|
node: &Node,
|
||||||
|
x_: f64,
|
||||||
|
y_: f64,
|
||||||
|
behavior: ScrollBehavior,
|
||||||
|
can_gc: CanGc,
|
||||||
|
) {
|
||||||
// The scroll offsets are immediatly updated since later calls
|
// The scroll offsets are immediatly updated since later calls
|
||||||
// to topScroll and others may access the properties before
|
// to topScroll and others may access the properties before
|
||||||
// webrender has a chance to update the offsets.
|
// webrender has a chance to update the offsets.
|
||||||
|
@ -2146,6 +2165,7 @@ impl Window {
|
||||||
scroll_id,
|
scroll_id,
|
||||||
behavior,
|
behavior,
|
||||||
None,
|
None,
|
||||||
|
can_gc,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2154,8 +2174,9 @@ impl Window {
|
||||||
element: TrustedNodeAddress,
|
element: TrustedNodeAddress,
|
||||||
pseudo: Option<PseudoElement>,
|
pseudo: Option<PseudoElement>,
|
||||||
property: PropertyId,
|
property: PropertyId,
|
||||||
|
can_gc: CanGc,
|
||||||
) -> DOMString {
|
) -> DOMString {
|
||||||
if !self.layout_reflow(QueryMsg::ResolvedStyleQuery) {
|
if !self.layout_reflow(QueryMsg::ResolvedStyleQuery, can_gc) {
|
||||||
return DOMString::new();
|
return DOMString::new();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2173,8 +2194,9 @@ impl Window {
|
||||||
pub fn inner_window_dimensions_query(
|
pub fn inner_window_dimensions_query(
|
||||||
&self,
|
&self,
|
||||||
browsing_context: BrowsingContextId,
|
browsing_context: BrowsingContextId,
|
||||||
|
can_gc: CanGc,
|
||||||
) -> Option<Size2D<f32, CSSPixel>> {
|
) -> Option<Size2D<f32, CSSPixel>> {
|
||||||
if !self.layout_reflow(QueryMsg::InnerWindowDimensionsQuery) {
|
if !self.layout_reflow(QueryMsg::InnerWindowDimensionsQuery, can_gc) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
self.layout
|
self.layout
|
||||||
|
@ -2183,8 +2205,12 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
pub fn offset_parent_query(&self, node: &Node) -> (Option<DomRoot<Element>>, UntypedRect<Au>) {
|
pub fn offset_parent_query(
|
||||||
if !self.layout_reflow(QueryMsg::OffsetParentQuery) {
|
&self,
|
||||||
|
node: &Node,
|
||||||
|
can_gc: CanGc,
|
||||||
|
) -> (Option<DomRoot<Element>>, UntypedRect<Au>) {
|
||||||
|
if !self.layout_reflow(QueryMsg::OffsetParentQuery, can_gc) {
|
||||||
return (None, Rect::zero());
|
return (None, Rect::zero());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2200,8 +2226,9 @@ impl Window {
|
||||||
&self,
|
&self,
|
||||||
node: &Node,
|
node: &Node,
|
||||||
point_in_node: UntypedPoint2D<f32>,
|
point_in_node: UntypedPoint2D<f32>,
|
||||||
|
can_gc: CanGc,
|
||||||
) -> Option<usize> {
|
) -> Option<usize> {
|
||||||
if !self.layout_reflow(QueryMsg::TextIndexQuery) {
|
if !self.layout_reflow(QueryMsg::TextIndexQuery, can_gc) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
self.layout
|
self.layout
|
||||||
|
@ -2252,7 +2279,7 @@ impl Window {
|
||||||
load_data.url.clone(),
|
load_data.url.clone(),
|
||||||
replace,
|
replace,
|
||||||
));
|
));
|
||||||
doc.check_and_scroll_fragment(fragment);
|
doc.check_and_scroll_fragment(fragment, CanGc::note());
|
||||||
let this = Trusted::new(self);
|
let this = Trusted::new(self);
|
||||||
let old_url = doc.url().into_string();
|
let old_url = doc.url().into_string();
|
||||||
let new_url = load_data.url.clone().into_string();
|
let new_url = load_data.url.clone().into_string();
|
||||||
|
|
|
@ -1727,12 +1727,12 @@ impl ScriptThread {
|
||||||
// https://html.spec.whatwg.org/multipage/#context-lost-steps.
|
// https://html.spec.whatwg.org/multipage/#context-lost-steps.
|
||||||
|
|
||||||
// Run the animation frame callbacks.
|
// Run the animation frame callbacks.
|
||||||
document.tick_all_animations(should_run_rafs);
|
document.tick_all_animations(should_run_rafs, can_gc);
|
||||||
|
|
||||||
// Run the resize observer steps.
|
// Run the resize observer steps.
|
||||||
let _realm = enter_realm(&*document);
|
let _realm = enter_realm(&*document);
|
||||||
let mut depth = Default::default();
|
let mut depth = Default::default();
|
||||||
while document.gather_active_resize_observations_at_depth(&depth) {
|
while document.gather_active_resize_observations_at_depth(&depth, can_gc) {
|
||||||
// Note: this will reflow the doc.
|
// Note: this will reflow the doc.
|
||||||
depth = document.broadcast_active_resize_observations(can_gc);
|
depth = document.broadcast_active_resize_observations(can_gc);
|
||||||
}
|
}
|
||||||
|
@ -1889,7 +1889,7 @@ impl ScriptThread {
|
||||||
},
|
},
|
||||||
FromConstellation(ConstellationControlMsg::Viewport(id, rect)) => self
|
FromConstellation(ConstellationControlMsg::Viewport(id, rect)) => self
|
||||||
.profile_event(ScriptThreadEventCategory::SetViewport, Some(id), || {
|
.profile_event(ScriptThreadEventCategory::SetViewport, Some(id), || {
|
||||||
self.handle_viewport(id, rect);
|
self.handle_viewport(id, rect, can_gc);
|
||||||
}),
|
}),
|
||||||
FromConstellation(ConstellationControlMsg::TickAllAnimations(
|
FromConstellation(ConstellationControlMsg::TickAllAnimations(
|
||||||
pipeline_id,
|
pipeline_id,
|
||||||
|
@ -2067,13 +2067,17 @@ impl ScriptThread {
|
||||||
|
|
||||||
let pending_reflows = window.get_pending_reflow_count();
|
let pending_reflows = window.get_pending_reflow_count();
|
||||||
if pending_reflows > 0 {
|
if pending_reflows > 0 {
|
||||||
window.reflow(ReflowGoal::Full, ReflowReason::PendingReflow);
|
window.reflow(ReflowGoal::Full, ReflowReason::PendingReflow, can_gc);
|
||||||
} else {
|
} else {
|
||||||
// Reflow currently happens when explicitly invoked by code that
|
// Reflow currently happens when explicitly invoked by code that
|
||||||
// knows the document could have been modified. This should really
|
// knows the document could have been modified. This should really
|
||||||
// be driven by the compositor on an as-needed basis instead, to
|
// be driven by the compositor on an as-needed basis instead, to
|
||||||
// minimize unnecessary work.
|
// minimize unnecessary work.
|
||||||
window.reflow(ReflowGoal::Full, ReflowReason::MissingExplicitReflow);
|
window.reflow(
|
||||||
|
ReflowGoal::Full,
|
||||||
|
ReflowReason::MissingExplicitReflow,
|
||||||
|
can_gc,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2554,7 +2558,7 @@ impl ScriptThread {
|
||||||
self.collect_reports(chan)
|
self.collect_reports(chan)
|
||||||
},
|
},
|
||||||
MainThreadScriptMsg::WorkletLoaded(pipeline_id) => {
|
MainThreadScriptMsg::WorkletLoaded(pipeline_id) => {
|
||||||
self.handle_worklet_loaded(pipeline_id)
|
self.handle_worklet_loaded(pipeline_id, CanGc::note())
|
||||||
},
|
},
|
||||||
MainThreadScriptMsg::RegisterPaintWorklet {
|
MainThreadScriptMsg::RegisterPaintWorklet {
|
||||||
pipeline_id,
|
pipeline_id,
|
||||||
|
@ -2840,7 +2844,7 @@ impl ScriptThread {
|
||||||
webdriver_handlers::handle_get_css(&documents, pipeline_id, node_id, name, reply)
|
webdriver_handlers::handle_get_css(&documents, pipeline_id, node_id, name, reply)
|
||||||
},
|
},
|
||||||
WebDriverScriptCommand::GetElementRect(node_id, reply) => {
|
WebDriverScriptCommand::GetElementRect(node_id, reply) => {
|
||||||
webdriver_handlers::handle_get_rect(&documents, pipeline_id, node_id, reply)
|
webdriver_handlers::handle_get_rect(&documents, pipeline_id, node_id, reply, can_gc)
|
||||||
},
|
},
|
||||||
WebDriverScriptCommand::GetBoundingClientRect(node_id, reply) => {
|
WebDriverScriptCommand::GetBoundingClientRect(node_id, reply) => {
|
||||||
webdriver_handlers::handle_get_bounding_client_rect(
|
webdriver_handlers::handle_get_bounding_client_rect(
|
||||||
|
@ -2918,11 +2922,11 @@ impl ScriptThread {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_viewport(&self, id: PipelineId, rect: Rect<f32>) {
|
fn handle_viewport(&self, id: PipelineId, rect: Rect<f32>, can_gc: CanGc) {
|
||||||
let document = self.documents.borrow().find_document(id);
|
let document = self.documents.borrow().find_document(id);
|
||||||
if let Some(document) = document {
|
if let Some(document) = document {
|
||||||
if document.window().set_page_clip_rect_with_new_viewport(rect) {
|
if document.window().set_page_clip_rect_with_new_viewport(rect) {
|
||||||
self.rebuild_and_force_reflow(&document, ReflowReason::Viewport);
|
self.rebuild_and_force_reflow(&document, ReflowReason::Viewport, can_gc);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3028,7 +3032,7 @@ impl ScriptThread {
|
||||||
);
|
);
|
||||||
let document = self.documents.borrow().find_document(id);
|
let document = self.documents.borrow().find_document(id);
|
||||||
if let Some(document) = document {
|
if let Some(document) = document {
|
||||||
document.set_activity(activity);
|
document.set_activity(activity, CanGc::note());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let mut loads = self.incomplete_loads.borrow_mut();
|
let mut loads = self.incomplete_loads.borrow_mut();
|
||||||
|
@ -3443,10 +3447,10 @@ impl ScriptThread {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handles a worklet being loaded. Does nothing if the page no longer exists.
|
/// Handles a worklet being loaded. Does nothing if the page no longer exists.
|
||||||
fn handle_worklet_loaded(&self, pipeline_id: PipelineId) {
|
fn handle_worklet_loaded(&self, pipeline_id: PipelineId, can_gc: CanGc) {
|
||||||
let document = self.documents.borrow().find_document(pipeline_id);
|
let document = self.documents.borrow().find_document(pipeline_id);
|
||||||
if let Some(document) = document {
|
if let Some(document) = document {
|
||||||
self.rebuild_and_force_reflow(&document, ReflowReason::WorkletLoaded);
|
self.rebuild_and_force_reflow(&document, ReflowReason::WorkletLoaded, can_gc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3904,10 +3908,10 @@ impl ScriptThread {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reflows non-incrementally, rebuilding the entire layout tree in the process.
|
/// Reflows non-incrementally, rebuilding the entire layout tree in the process.
|
||||||
fn rebuild_and_force_reflow(&self, document: &Document, reason: ReflowReason) {
|
fn rebuild_and_force_reflow(&self, document: &Document, reason: ReflowReason, can_gc: CanGc) {
|
||||||
let window = window_from_node(document);
|
let window = window_from_node(document);
|
||||||
document.dirty_all_nodes();
|
document.dirty_all_nodes();
|
||||||
window.reflow(ReflowGoal::Full, reason);
|
window.reflow(ReflowGoal::Full, reason, can_gc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Queue compositor events for later dispatching as part of a
|
/// Queue compositor events for later dispatching as part of a
|
||||||
|
|
|
@ -95,7 +95,7 @@ impl OneshotTimerCallback {
|
||||||
OneshotTimerCallback::EventSourceTimeout(callback) => callback.invoke(),
|
OneshotTimerCallback::EventSourceTimeout(callback) => callback.invoke(),
|
||||||
OneshotTimerCallback::JsTimer(task) => task.invoke(this, js_timers),
|
OneshotTimerCallback::JsTimer(task) => task.invoke(this, js_timers),
|
||||||
OneshotTimerCallback::TestBindingCallback(callback) => callback.invoke(),
|
OneshotTimerCallback::TestBindingCallback(callback) => callback.invoke(),
|
||||||
OneshotTimerCallback::FakeRequestAnimationFrame(callback) => callback.invoke(),
|
OneshotTimerCallback::FakeRequestAnimationFrame(callback) => callback.invoke(can_gc),
|
||||||
OneshotTimerCallback::RefreshRedirectDue(callback) => callback.invoke(can_gc),
|
OneshotTimerCallback::RefreshRedirectDue(callback) => callback.invoke(can_gc),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -388,8 +388,8 @@ fn get_element_in_view_center_point(element: &Element, can_gc: CanGc) -> Option<
|
||||||
let width = rectangle.Width().round() as i64;
|
let width = rectangle.Width().round() as i64;
|
||||||
let height = rectangle.Height().round() as i64;
|
let height = rectangle.Height().round() as i64;
|
||||||
|
|
||||||
let client_width = body.ClientWidth() as i64;
|
let client_width = body.ClientWidth(can_gc) as i64;
|
||||||
let client_height = body.ClientHeight() as i64;
|
let client_height = body.ClientHeight(can_gc) as i64;
|
||||||
|
|
||||||
// Steps 2 - 5
|
// Steps 2 - 5
|
||||||
let left = cmp::max(0, cmp::min(x, x + width));
|
let left = cmp::max(0, cmp::min(x, x + width));
|
||||||
|
@ -881,6 +881,7 @@ pub fn handle_get_rect(
|
||||||
pipeline: PipelineId,
|
pipeline: PipelineId,
|
||||||
element_id: String,
|
element_id: String,
|
||||||
reply: IpcSender<Result<Rect<f64>, ErrorStatus>>,
|
reply: IpcSender<Result<Rect<f64>, ErrorStatus>>,
|
||||||
|
can_gc: CanGc,
|
||||||
) {
|
) {
|
||||||
reply
|
reply
|
||||||
.send(
|
.send(
|
||||||
|
@ -892,15 +893,15 @@ pub fn handle_get_rect(
|
||||||
let mut x = 0;
|
let mut x = 0;
|
||||||
let mut y = 0;
|
let mut y = 0;
|
||||||
|
|
||||||
let mut offset_parent = html_element.GetOffsetParent();
|
let mut offset_parent = html_element.GetOffsetParent(can_gc);
|
||||||
|
|
||||||
// Step 2
|
// Step 2
|
||||||
while let Some(element) = offset_parent {
|
while let Some(element) = offset_parent {
|
||||||
offset_parent = match element.downcast::<HTMLElement>() {
|
offset_parent = match element.downcast::<HTMLElement>() {
|
||||||
Some(elem) => {
|
Some(elem) => {
|
||||||
x += elem.OffsetLeft();
|
x += elem.OffsetLeft(can_gc);
|
||||||
y += elem.OffsetTop();
|
y += elem.OffsetTop(can_gc);
|
||||||
elem.GetOffsetParent()
|
elem.GetOffsetParent(can_gc)
|
||||||
},
|
},
|
||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
|
@ -909,8 +910,8 @@ pub fn handle_get_rect(
|
||||||
Ok(Rect::new(
|
Ok(Rect::new(
|
||||||
Point2D::new(x as f64, y as f64),
|
Point2D::new(x as f64, y as f64),
|
||||||
Size2D::new(
|
Size2D::new(
|
||||||
html_element.OffsetWidth() as f64,
|
html_element.OffsetWidth(can_gc) as f64,
|
||||||
html_element.OffsetHeight() as f64,
|
html_element.OffsetHeight(can_gc) as f64,
|
||||||
),
|
),
|
||||||
))
|
))
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue