mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Upgrade to rustc 1.21.0-nightly (13d94d5fa 2017-08-10)
This commit is contained in:
parent
41fb10c589
commit
b5a4b8d6a0
40 changed files with 73 additions and 79 deletions
6
Cargo.lock
generated
6
Cargo.lock
generated
|
@ -3587,7 +3587,7 @@ version = "0.1.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"xcb 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"xcb 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3602,7 +3602,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "xcb"
|
name = "xcb"
|
||||||
version = "0.7.6"
|
version = "0.7.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -3929,7 +3929,7 @@ dependencies = [
|
||||||
"checksum x11 2.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db27c597c187da52194a4b8232e7d869503911aab9ff726fefb76d7a830f78ed"
|
"checksum x11 2.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db27c597c187da52194a4b8232e7d869503911aab9ff726fefb76d7a830f78ed"
|
||||||
"checksum x11-clipboard 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "731230b8edcbb9d99247105e4c9ec0a538594d50ad68d2afa8662195f9db2973"
|
"checksum x11-clipboard 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "731230b8edcbb9d99247105e4c9ec0a538594d50ad68d2afa8662195f9db2973"
|
||||||
"checksum x11-dl 2.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "326c500cdc166fd7c70dd8c8a829cd5c0ce7be5a5d98c25817de2b9bdc67faf8"
|
"checksum x11-dl 2.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "326c500cdc166fd7c70dd8c8a829cd5c0ce7be5a5d98c25817de2b9bdc67faf8"
|
||||||
"checksum xcb 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "63e3a849b73e4e1905e4f4d48f1750429bc86ea9f473632ab382a6f69ecb6b33"
|
"checksum xcb 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)" = "7cede38417fcdf2f0a9d8abf1cea1c1b066320a8a316e9583a0d717c334fafb2"
|
||||||
"checksum xdg 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a66b7c2281ebde13cf4391d70d4c7e5946c3c25e72a7b859ca8f677dcd0b0c61"
|
"checksum xdg 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a66b7c2281ebde13cf4391d70d4c7e5946c3c25e72a7b859ca8f677dcd0b0c61"
|
||||||
"checksum xi-unicode 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "12ea8eda4b1eb72f02d148402e23832d56a33f55d8c1b2d5bcdde91d79d47cb1"
|
"checksum xi-unicode 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "12ea8eda4b1eb72f02d148402e23832d56a33f55d8c1b2d5bcdde91d79d47cb1"
|
||||||
"checksum xml-rs 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7ec6c39eaa68382c8e31e35239402c0a9489d4141a8ceb0c716099a0b515b562"
|
"checksum xml-rs 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7ec6c39eaa68382c8e31e35239402c0a9489d4141a8ceb0c716099a0b515b562"
|
||||||
|
|
|
@ -306,7 +306,7 @@ fn run_server(sender: Sender<DevtoolsControlMsg>,
|
||||||
columnNumber: console_message.columnNumber,
|
columnNumber: console_message.columnNumber,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
for mut stream in &mut *console_actor.streams.borrow_mut() {
|
for stream in &mut *console_actor.streams.borrow_mut() {
|
||||||
stream.write_json_packet(&msg);
|
stream.write_json_packet(&msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ pub fn update_animation_state(constellation_chan: &IpcSender<ConstellationMsg>,
|
||||||
// run.
|
// run.
|
||||||
if let Some(ref mut animations) = running_animations.get_mut(node) {
|
if let Some(ref mut animations) = running_animations.get_mut(node) {
|
||||||
// TODO: This being linear is probably not optimal.
|
// TODO: This being linear is probably not optimal.
|
||||||
for mut anim in animations.iter_mut() {
|
for anim in animations.iter_mut() {
|
||||||
if let Animation::Keyframes(_, ref anim_name, ref mut anim_state) = *anim {
|
if let Animation::Keyframes(_, ref anim_name, ref mut anim_state) = *anim {
|
||||||
if *name == *anim_name {
|
if *name == *anim_name {
|
||||||
debug!("update_animation_state: Found other animation {}", name);
|
debug!("update_animation_state: Found other animation {}", name);
|
||||||
|
|
|
@ -1921,7 +1921,7 @@ impl Legalizer {
|
||||||
/// true for anonymous block children of flex flows.
|
/// true for anonymous block children of flex flows.
|
||||||
fn try_to_add_child(&mut self, context: &SharedStyleContext, parent: &mut FlowRef, child: &mut FlowRef)
|
fn try_to_add_child(&mut self, context: &SharedStyleContext, parent: &mut FlowRef, child: &mut FlowRef)
|
||||||
-> bool {
|
-> bool {
|
||||||
let mut parent = self.stack.last_mut().unwrap_or(parent);
|
let parent = self.stack.last_mut().unwrap_or(parent);
|
||||||
let (parent_class, child_class) = (parent.class(), child.class());
|
let (parent_class, child_class) = (parent.class(), child.class());
|
||||||
match (parent_class, child_class) {
|
match (parent_class, child_class) {
|
||||||
(FlowClass::TableWrapper, FlowClass::Table) |
|
(FlowClass::TableWrapper, FlowClass::Table) |
|
||||||
|
@ -1962,7 +1962,7 @@ impl Legalizer {
|
||||||
} else {
|
} else {
|
||||||
IS_BLOCK_FLEX_ITEM
|
IS_BLOCK_FLEX_ITEM
|
||||||
};
|
};
|
||||||
let mut block = FlowRef::deref_mut(&mut block_wrapper).as_mut_block();
|
let block = FlowRef::deref_mut(&mut block_wrapper).as_mut_block();
|
||||||
block.base.flags.insert(MARGINS_CANNOT_COLLAPSE);
|
block.base.flags.insert(MARGINS_CANNOT_COLLAPSE);
|
||||||
block.fragment.flags.insert(flag);
|
block.fragment.flags.insert(flag);
|
||||||
}
|
}
|
||||||
|
@ -1979,7 +1979,7 @@ impl Legalizer {
|
||||||
} else {
|
} else {
|
||||||
IS_BLOCK_FLEX_ITEM
|
IS_BLOCK_FLEX_ITEM
|
||||||
};
|
};
|
||||||
let mut block = FlowRef::deref_mut(child).as_mut_block();
|
let block = FlowRef::deref_mut(child).as_mut_block();
|
||||||
block.base.flags.insert(MARGINS_CANNOT_COLLAPSE);
|
block.base.flags.insert(MARGINS_CANNOT_COLLAPSE);
|
||||||
block.fragment.flags.insert(flag);
|
block.fragment.flags.insert(flag);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2731,7 +2731,7 @@ impl InlineFlowDisplayListBuilding for InlineFlow {
|
||||||
self.base.clip_and_scroll_info = Some(state.current_clip_and_scroll_info);
|
self.base.clip_and_scroll_info = Some(state.current_clip_and_scroll_info);
|
||||||
self.base.clip = state.clip_stack.last().cloned().unwrap_or_else(max_rect);
|
self.base.clip = state.clip_stack.last().cloned().unwrap_or_else(max_rect);
|
||||||
|
|
||||||
for mut fragment in self.fragments.fragments.iter_mut() {
|
for fragment in self.fragments.fragments.iter_mut() {
|
||||||
let previous_cb_clip_scroll_info = state.containing_block_clip_and_scroll_info;
|
let previous_cb_clip_scroll_info = state.containing_block_clip_and_scroll_info;
|
||||||
if establishes_containing_block_for_absolute(fragment.style.get_box().position) {
|
if establishes_containing_block_for_absolute(fragment.style.get_box().position) {
|
||||||
state.containing_block_clip_and_scroll_info = state.current_clip_and_scroll_info;
|
state.containing_block_clip_and_scroll_info = state.current_clip_and_scroll_info;
|
||||||
|
|
|
@ -415,7 +415,7 @@ impl FlexFlow {
|
||||||
|
|
||||||
let items = &mut self.items[start..];
|
let items = &mut self.items[start..];
|
||||||
let mut children = self.block_flow.base.children.random_access_mut();
|
let mut children = self.block_flow.base.children.random_access_mut();
|
||||||
for mut item in items {
|
for item in items {
|
||||||
let kid = children.get(item.index);
|
let kid = children.get(item.index);
|
||||||
item.init_sizes(kid, container_size, self.main_mode);
|
item.init_sizes(kid, container_size, self.main_mode);
|
||||||
let outer_main_size = item.outer_main_size(kid, self.main_mode);
|
let outer_main_size = item.outer_main_size(kid, self.main_mode);
|
||||||
|
@ -607,7 +607,7 @@ impl FlexFlow {
|
||||||
|
|
||||||
let mut children = self.block_flow.base.children.random_access_mut();
|
let mut children = self.block_flow.base.children.random_access_mut();
|
||||||
for item in items.iter_mut() {
|
for item in items.iter_mut() {
|
||||||
let mut block = children.get(item.index).as_mut_block();
|
let block = children.get(item.index).as_mut_block();
|
||||||
|
|
||||||
block.base.block_container_writing_mode = container_mode;
|
block.base.block_container_writing_mode = container_mode;
|
||||||
block.base.block_container_inline_size = inline_size;
|
block.base.block_container_inline_size = inline_size;
|
||||||
|
@ -659,7 +659,7 @@ impl FlexFlow {
|
||||||
|
|
||||||
let mut children = self.block_flow.base.children.random_access_mut();
|
let mut children = self.block_flow.base.children.random_access_mut();
|
||||||
for item in &mut self.items {
|
for item in &mut self.items {
|
||||||
let mut base = flow::mut_base(children.get(item.index));
|
let base = flow::mut_base(children.get(item.index));
|
||||||
if !self.main_reverse {
|
if !self.main_reverse {
|
||||||
base.position.start.b = cur_b;
|
base.position.start.b = cur_b;
|
||||||
cur_b = cur_b + base.position.size.block;
|
cur_b = cur_b + base.position.size.block;
|
||||||
|
|
|
@ -435,7 +435,7 @@ impl LineBreaker {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let last_fragment_index = self.pending_line.range.end() - FragmentIndex(1);
|
let last_fragment_index = self.pending_line.range.end() - FragmentIndex(1);
|
||||||
let mut fragment = &mut self.new_fragments[last_fragment_index.get() as usize];
|
let fragment = &mut self.new_fragments[last_fragment_index.get() as usize];
|
||||||
|
|
||||||
let old_fragment_inline_size = fragment.border_box.size.inline;
|
let old_fragment_inline_size = fragment.border_box.size.inline;
|
||||||
|
|
||||||
|
@ -1047,7 +1047,7 @@ impl InlineFlow {
|
||||||
let space_per_expansion_opportunity = slack_inline_size / expansion_opportunities as i32;
|
let space_per_expansion_opportunity = slack_inline_size / expansion_opportunities as i32;
|
||||||
for fragment_index in line.range.each_index() {
|
for fragment_index in line.range.each_index() {
|
||||||
let fragment = fragments.get_mut(fragment_index.to_usize());
|
let fragment = fragments.get_mut(fragment_index.to_usize());
|
||||||
let mut scanned_text_fragment_info = match fragment.specific {
|
let scanned_text_fragment_info = match fragment.specific {
|
||||||
SpecificFragmentInfo::ScannedText(ref mut info) if !info.range.is_empty() => info,
|
SpecificFragmentInfo::ScannedText(ref mut info) if !info.range.is_empty() => info,
|
||||||
_ => continue
|
_ => continue
|
||||||
};
|
};
|
||||||
|
|
|
@ -117,7 +117,7 @@ pub fn store_overflow(layout_context: &LayoutContext, flow: &mut Flow) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for mut kid in flow::mut_base(flow).child_iter_mut() {
|
for kid in flow::mut_base(flow).child_iter_mut() {
|
||||||
store_overflow(layout_context, kid);
|
store_overflow(layout_context, kid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -136,7 +136,7 @@ impl TableCellFlow {
|
||||||
}
|
}
|
||||||
|
|
||||||
for kid in flow::mut_base(self).children.iter_mut() {
|
for kid in flow::mut_base(self).children.iter_mut() {
|
||||||
let mut kid_base = flow::mut_base(kid);
|
let kid_base = flow::mut_base(kid);
|
||||||
if !kid_base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
|
if !kid_base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
|
||||||
kid_base.position.start.b += offset
|
kid_base.position.start.b += offset
|
||||||
}
|
}
|
||||||
|
|
|
@ -460,7 +460,7 @@ fn split_first_fragment_at_newline_if_necessary(fragments: &mut LinkedList<Fragm
|
||||||
}
|
}
|
||||||
|
|
||||||
let new_fragment = {
|
let new_fragment = {
|
||||||
let mut first_fragment = fragments.front_mut().unwrap();
|
let first_fragment = fragments.front_mut().unwrap();
|
||||||
let string_before;
|
let string_before;
|
||||||
let selection_before;
|
let selection_before;
|
||||||
{
|
{
|
||||||
|
|
|
@ -103,7 +103,7 @@ impl CookieStorage {
|
||||||
|
|
||||||
// Step 12
|
// Step 12
|
||||||
let domain = reg_host(&cookie.cookie.domain().as_ref().unwrap_or(&""));
|
let domain = reg_host(&cookie.cookie.domain().as_ref().unwrap_or(&""));
|
||||||
let mut cookies = self.cookies_map.entry(domain).or_insert(vec![]);
|
let cookies = self.cookies_map.entry(domain).or_insert(vec![]);
|
||||||
|
|
||||||
if cookies.len() == self.max_per_host {
|
if cookies.len() == self.max_per_host {
|
||||||
let old_len = cookies.len();
|
let old_len = cookies.len();
|
||||||
|
|
|
@ -33,7 +33,7 @@ pub fn cleanup() {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
if let Some(mut hbs) = hbs_opt_box {
|
if let Some(mut hbs) = hbs_opt_box {
|
||||||
for (_, mut v) in hbs.iter_mut() {
|
for (_, v) in hbs.iter_mut() {
|
||||||
// log any remaining heartbeat records before dropping
|
// log any remaining heartbeat records before dropping
|
||||||
log_heartbeat_records(v);
|
log_heartbeat_records(v);
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ pub fn maybe_heartbeat(category: &ProfilerCategory,
|
||||||
if !(*hbs_ptr).contains_key(category) {
|
if !(*hbs_ptr).contains_key(category) {
|
||||||
maybe_create_heartbeat(&mut (*hbs_ptr), category.clone());
|
maybe_create_heartbeat(&mut (*hbs_ptr), category.clone());
|
||||||
}
|
}
|
||||||
if let Some(mut h) = (*hbs_ptr).get_mut(category) {
|
if let Some(h) = (*hbs_ptr).get_mut(category) {
|
||||||
(*h).heartbeat(0, 1, start_time, end_time, start_energy, end_energy);
|
(*h).heartbeat(0, 1, start_time, end_time, start_energy, end_energy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -469,7 +469,7 @@ impl RootCollection {
|
||||||
/// Start tracking a stack-based root
|
/// Start tracking a stack-based root
|
||||||
unsafe fn root(&self, untracked_reflector: *const Reflector) {
|
unsafe fn root(&self, untracked_reflector: *const Reflector) {
|
||||||
debug_assert!(thread_state::get().is_script());
|
debug_assert!(thread_state::get().is_script());
|
||||||
let mut roots = &mut *self.roots.get();
|
let roots = &mut *self.roots.get();
|
||||||
roots.push(untracked_reflector);
|
roots.push(untracked_reflector);
|
||||||
assert!(!(*untracked_reflector).get_jsobject().is_null())
|
assert!(!(*untracked_reflector).get_jsobject().is_null())
|
||||||
}
|
}
|
||||||
|
@ -479,7 +479,7 @@ impl RootCollection {
|
||||||
assert!(!tracked_reflector.is_null());
|
assert!(!tracked_reflector.is_null());
|
||||||
assert!(!(*tracked_reflector).get_jsobject().is_null());
|
assert!(!(*tracked_reflector).get_jsobject().is_null());
|
||||||
debug_assert!(thread_state::get().is_script());
|
debug_assert!(thread_state::get().is_script());
|
||||||
let mut roots = &mut *self.roots.get();
|
let roots = &mut *self.roots.get();
|
||||||
match roots.iter().rposition(|r| *r == tracked_reflector) {
|
match roots.iter().rposition(|r| *r == tracked_reflector) {
|
||||||
Some(idx) => {
|
Some(idx) => {
|
||||||
roots.remove(idx);
|
roots.remove(idx);
|
||||||
|
|
|
@ -238,7 +238,7 @@ impl CSSStyleDeclaration {
|
||||||
return Err(Error::NoModificationAllowed);
|
return Err(Error::NoModificationAllowed);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.owner.mutate_associated_block(|ref mut pdb, mut changed| {
|
self.owner.mutate_associated_block(|pdb, changed| {
|
||||||
if value.is_empty() {
|
if value.is_empty() {
|
||||||
// Step 3
|
// Step 3
|
||||||
*changed = pdb.remove_property(&id);
|
*changed = pdb.remove_property(&id);
|
||||||
|
@ -360,7 +360,7 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
|
||||||
_ => return Ok(()),
|
_ => return Ok(()),
|
||||||
};
|
};
|
||||||
|
|
||||||
self.owner.mutate_associated_block(|ref mut pdb, mut changed| {
|
self.owner.mutate_associated_block(|pdb, changed| {
|
||||||
// Step 5 & 6
|
// Step 5 & 6
|
||||||
*changed = pdb.set_importance(&id, importance);
|
*changed = pdb.set_importance(&id, importance);
|
||||||
});
|
});
|
||||||
|
@ -388,7 +388,7 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut string = String::new();
|
let mut string = String::new();
|
||||||
self.owner.mutate_associated_block(|mut pdb, mut changed| {
|
self.owner.mutate_associated_block(|pdb, changed| {
|
||||||
pdb.property_value_to_css(&id, &mut string).unwrap();
|
pdb.property_value_to_css(&id, &mut string).unwrap();
|
||||||
*changed = pdb.remove_property(&id);
|
*changed = pdb.remove_property(&id);
|
||||||
});
|
});
|
||||||
|
@ -438,7 +438,7 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
|
||||||
}
|
}
|
||||||
|
|
||||||
let quirks_mode = window.Document().quirks_mode();
|
let quirks_mode = window.Document().quirks_mode();
|
||||||
self.owner.mutate_associated_block(|mut pdb, mut _changed| {
|
self.owner.mutate_associated_block(|pdb, _changed| {
|
||||||
// Step 3
|
// Step 3
|
||||||
*pdb = parse_style_attribute(&value,
|
*pdb = parse_style_attribute(&value,
|
||||||
&self.owner.base_url(),
|
&self.owner.base_url(),
|
||||||
|
|
|
@ -100,7 +100,7 @@ impl CSSStyleRuleMethods for CSSStyleRule {
|
||||||
if let Ok(mut s) = SelectorList::parse(&parser, &mut css_parser) {
|
if let Ok(mut s) = SelectorList::parse(&parser, &mut css_parser) {
|
||||||
// This mirrors what we do in CSSStyleOwner::mutate_associated_block.
|
// This mirrors what we do in CSSStyleOwner::mutate_associated_block.
|
||||||
let mut guard = self.cssrule.shared_lock().write();
|
let mut guard = self.cssrule.shared_lock().write();
|
||||||
let mut stylerule = self.stylerule.write_with(&mut guard);
|
let stylerule = self.stylerule.write_with(&mut guard);
|
||||||
mem::swap(&mut stylerule.selectors, &mut s);
|
mem::swap(&mut stylerule.selectors, &mut s);
|
||||||
// It seems like we will want to avoid having to invalidate all
|
// It seems like we will want to avoid having to invalidate all
|
||||||
// stylesheets eventually!
|
// stylesheets eventually!
|
||||||
|
|
|
@ -633,7 +633,7 @@ impl Document {
|
||||||
// reset_form_owner_for_listeners -> reset_form_owner -> GetElementById
|
// reset_form_owner_for_listeners -> reset_form_owner -> GetElementById
|
||||||
{
|
{
|
||||||
let mut id_map = self.id_map.borrow_mut();
|
let mut id_map = self.id_map.borrow_mut();
|
||||||
let mut elements = id_map.entry(id.clone()).or_insert(Vec::new());
|
let elements = id_map.entry(id.clone()).or_insert(Vec::new());
|
||||||
elements.insert_pre_order(element, root.r().upcast::<Node>());
|
elements.insert_pre_order(element, root.r().upcast::<Node>());
|
||||||
}
|
}
|
||||||
self.reset_form_owner_for_listeners(&id);
|
self.reset_form_owner_for_listeners(&id);
|
||||||
|
@ -642,7 +642,7 @@ impl Document {
|
||||||
pub fn register_form_id_listener<T: ?Sized + FormControl>(&self, id: DOMString, listener: &T) {
|
pub fn register_form_id_listener<T: ?Sized + FormControl>(&self, id: DOMString, listener: &T) {
|
||||||
let mut map = self.form_id_listener_map.borrow_mut();
|
let mut map = self.form_id_listener_map.borrow_mut();
|
||||||
let listener = listener.to_element();
|
let listener = listener.to_element();
|
||||||
let mut set = map.entry(Atom::from(id)).or_insert(HashSet::new());
|
let set = map.entry(Atom::from(id)).or_insert(HashSet::new());
|
||||||
set.insert(JS::from_ref(listener));
|
set.insert(JS::from_ref(listener));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1559,7 +1559,7 @@ impl Document {
|
||||||
/// https://html.spec.whatwg.org/multipage/#dom-window-cancelanimationframe
|
/// https://html.spec.whatwg.org/multipage/#dom-window-cancelanimationframe
|
||||||
pub fn cancel_animation_frame(&self, ident: u32) {
|
pub fn cancel_animation_frame(&self, ident: u32) {
|
||||||
let mut list = self.animation_frame_list.borrow_mut();
|
let mut list = self.animation_frame_list.borrow_mut();
|
||||||
if let Some(mut pair) = list.iter_mut().find(|pair| pair.0 == ident) {
|
if let Some(pair) = list.iter_mut().find(|pair| pair.0 == ident) {
|
||||||
pair.1 = None;
|
pair.1 = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2391,7 +2391,7 @@ impl Document {
|
||||||
if entry.snapshot.is_none() {
|
if entry.snapshot.is_none() {
|
||||||
entry.snapshot = Some(Snapshot::new(el.html_element_in_html_document()));
|
entry.snapshot = Some(Snapshot::new(el.html_element_in_html_document()));
|
||||||
}
|
}
|
||||||
let mut snapshot = entry.snapshot.as_mut().unwrap();
|
let snapshot = entry.snapshot.as_mut().unwrap();
|
||||||
if snapshot.state.is_none() {
|
if snapshot.state.is_none() {
|
||||||
snapshot.state = Some(el.state());
|
snapshot.state = Some(el.state());
|
||||||
}
|
}
|
||||||
|
@ -2418,7 +2418,7 @@ impl Document {
|
||||||
entry.hint.insert(RESTYLE_SELF);
|
entry.hint.insert(RESTYLE_SELF);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut snapshot = entry.snapshot.as_mut().unwrap();
|
let snapshot = entry.snapshot.as_mut().unwrap();
|
||||||
if attr.local_name() == &local_name!("id") {
|
if attr.local_name() == &local_name!("id") {
|
||||||
snapshot.id_changed = true;
|
snapshot.id_changed = true;
|
||||||
} else if attr.local_name() == &local_name!("class") {
|
} else if attr.local_name() == &local_name!("class") {
|
||||||
|
@ -4019,7 +4019,7 @@ impl PendingInOrderScriptVec {
|
||||||
|
|
||||||
fn loaded(&self, element: &HTMLScriptElement, result: ScriptResult) {
|
fn loaded(&self, element: &HTMLScriptElement, result: ScriptResult) {
|
||||||
let mut scripts = self.scripts.borrow_mut();
|
let mut scripts = self.scripts.borrow_mut();
|
||||||
let mut entry = scripts.iter_mut().find(|entry| &*entry.element == element).unwrap();
|
let entry = scripts.iter_mut().find(|entry| &*entry.element == element).unwrap();
|
||||||
entry.loaded(result);
|
entry.loaded(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ impl MediaListMethods for MediaList {
|
||||||
// https://drafts.csswg.org/cssom/#dom-medialist-mediatext
|
// https://drafts.csswg.org/cssom/#dom-medialist-mediatext
|
||||||
fn SetMediaText(&self, value: DOMString) {
|
fn SetMediaText(&self, value: DOMString) {
|
||||||
let mut guard = self.shared_lock().write();
|
let mut guard = self.shared_lock().write();
|
||||||
let mut media_queries = self.media_queries.write_with(&mut guard);
|
let media_queries = self.media_queries.write_with(&mut guard);
|
||||||
// Step 2
|
// Step 2
|
||||||
if value.is_empty() {
|
if value.is_empty() {
|
||||||
// Step 1
|
// Step 1
|
||||||
|
@ -154,7 +154,7 @@ impl MediaListMethods for MediaList {
|
||||||
// Step 3
|
// Step 3
|
||||||
let m_serialized = m.unwrap().to_css_string();
|
let m_serialized = m.unwrap().to_css_string();
|
||||||
let mut guard = self.shared_lock().write();
|
let mut guard = self.shared_lock().write();
|
||||||
let mut media_list = self.media_queries.write_with(&mut guard);
|
let media_list = self.media_queries.write_with(&mut guard);
|
||||||
let new_vec = media_list.media_queries.drain(..)
|
let new_vec = media_list.media_queries.drain(..)
|
||||||
.filter(|q| m_serialized != q.to_css_string())
|
.filter(|q| m_serialized != q.to_css_string())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
|
@ -1049,7 +1049,7 @@ impl WeakRangeVec {
|
||||||
let offset = context.index();
|
let offset = context.index();
|
||||||
let parent = context.parent;
|
let parent = context.parent;
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut ranges = &mut *self.cell.get();
|
let ranges = &mut *self.cell.get();
|
||||||
|
|
||||||
ranges.update(|entry| {
|
ranges.update(|entry| {
|
||||||
let range = entry.root().unwrap();
|
let range = entry.root().unwrap();
|
||||||
|
@ -1076,7 +1076,7 @@ impl WeakRangeVec {
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut ranges = &mut *self.cell.get();
|
let ranges = &mut *self.cell.get();
|
||||||
|
|
||||||
ranges.update(|entry| {
|
ranges.update(|entry| {
|
||||||
let range = entry.root().unwrap();
|
let range = entry.root().unwrap();
|
||||||
|
|
|
@ -568,7 +568,7 @@ impl TreeSink for Sink {
|
||||||
}
|
}
|
||||||
let node = self.new_parse_node();
|
let node = self.new_parse_node();
|
||||||
{
|
{
|
||||||
let mut data = self.get_parse_node_data_mut(&target.id);
|
let data = self.get_parse_node_data_mut(&target.id);
|
||||||
data.contents = Some(node.clone());
|
data.contents = Some(node.clone());
|
||||||
}
|
}
|
||||||
self.send_op(ParseOperation::GetTemplateContents { target: target.id, contents: node.id });
|
self.send_op(ParseOperation::GetTemplateContents { target: target.id, contents: node.id });
|
||||||
|
@ -596,7 +596,7 @@ impl TreeSink for Sink {
|
||||||
let mut node = self.new_parse_node();
|
let mut node = self.new_parse_node();
|
||||||
node.qual_name = Some(name.clone());
|
node.qual_name = Some(name.clone());
|
||||||
{
|
{
|
||||||
let mut node_data = self.get_parse_node_data_mut(&node.id);
|
let node_data = self.get_parse_node_data_mut(&node.id);
|
||||||
node_data.is_integration_point = html_attrs.iter()
|
node_data.is_integration_point = html_attrs.iter()
|
||||||
.any(|attr| {
|
.any(|attr| {
|
||||||
let attr_value = &String::from(attr.value.clone());
|
let attr_value = &String::from(attr.value.clone());
|
||||||
|
|
|
@ -96,8 +96,8 @@ impl URL {
|
||||||
|
|
||||||
// https://w3c.github.io/FileAPI/#dfn-createObjectURL
|
// https://w3c.github.io/FileAPI/#dfn-createObjectURL
|
||||||
pub fn CreateObjectURL(global: &GlobalScope, blob: &Blob) -> DOMString {
|
pub fn CreateObjectURL(global: &GlobalScope, blob: &Blob) -> DOMString {
|
||||||
/// XXX: Second field is an unicode-serialized Origin, it is a temporary workaround
|
// XXX: Second field is an unicode-serialized Origin, it is a temporary workaround
|
||||||
/// and should not be trusted. See issue https://github.com/servo/servo/issues/11722
|
// and should not be trusted. See issue https://github.com/servo/servo/issues/11722
|
||||||
let origin = get_blob_origin(&global.get_url());
|
let origin = get_blob_origin(&global.get_url());
|
||||||
|
|
||||||
let id = blob.get_blob_url_id();
|
let id = blob.get_blob_url_id();
|
||||||
|
|
|
@ -268,7 +268,7 @@ impl VRDisplayMethods for VRDisplay {
|
||||||
fn CancelAnimationFrame(&self, handle: u32) {
|
fn CancelAnimationFrame(&self, handle: u32) {
|
||||||
if self.presenting.get() {
|
if self.presenting.get() {
|
||||||
let mut list = self.raf_callback_list.borrow_mut();
|
let mut list = self.raf_callback_list.borrow_mut();
|
||||||
if let Some(mut pair) = list.iter_mut().find(|pair| pair.0 == handle) {
|
if let Some(pair) = list.iter_mut().find(|pair| pair.0 == handle) {
|
||||||
pair.1 = None;
|
pair.1 = None;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -2434,7 +2434,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
typedarray!(in(cx) let mut pixels_data: ArrayBufferView = pixels);
|
typedarray!(in(cx) let mut pixels_data: ArrayBufferView = pixels);
|
||||||
let (array_type, mut data) = match { pixels_data.as_mut() } {
|
let (array_type, data) = match { pixels_data.as_mut() } {
|
||||||
Ok(data) => (data.get_array_type(), data.as_mut_slice()),
|
Ok(data) => (data.get_array_type(), data.as_mut_slice()),
|
||||||
Err(_) => return Err(Error::Type("Not an ArrayBufferView".to_owned())),
|
Err(_) => return Err(Error::Type("Not an ArrayBufferView".to_owned())),
|
||||||
};
|
};
|
||||||
|
|
|
@ -627,7 +627,7 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
|
||||||
|
|
||||||
if !content_type_set {
|
if !content_type_set {
|
||||||
let ct = request.headers.get_mut::<ContentType>();
|
let ct = request.headers.get_mut::<ContentType>();
|
||||||
if let Some(mut ct) = ct {
|
if let Some(ct) = ct {
|
||||||
if let Some(encoding) = encoding {
|
if let Some(encoding) = encoding {
|
||||||
for param in &mut (ct.0).2 {
|
for param in &mut (ct.0).2 {
|
||||||
if param.0 == MimeAttr::Charset {
|
if param.0 == MimeAttr::Charset {
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#![feature(mpsc_select)]
|
#![feature(mpsc_select)]
|
||||||
#![feature(nonzero)]
|
#![feature(nonzero)]
|
||||||
#![feature(on_unimplemented)]
|
#![feature(on_unimplemented)]
|
||||||
#![feature(option_entry)]
|
|
||||||
#![feature(plugin)]
|
#![feature(plugin)]
|
||||||
#![feature(proc_macro)]
|
#![feature(proc_macro)]
|
||||||
#![feature(stmt_expr_attributes)]
|
#![feature(stmt_expr_attributes)]
|
||||||
|
|
|
@ -182,7 +182,7 @@ impl<'a, 'b, 'tcx> visit::Visitor<'tcx> for FnDefVisitor<'a, 'b, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
match expr.node {
|
match expr.node {
|
||||||
/// Trait casts from #[must_root] types are not allowed
|
// Trait casts from #[must_root] types are not allowed
|
||||||
hir::ExprCast(ref subexpr, _) => require_rooted(cx, self.in_new_function, &*subexpr),
|
hir::ExprCast(ref subexpr, _) => require_rooted(cx, self.in_new_function, &*subexpr),
|
||||||
// This catches assignments... the main point of this would be to catch mutable
|
// This catches assignments... the main point of this would be to catch mutable
|
||||||
// references to `JS<T>`.
|
// references to `JS<T>`.
|
||||||
|
@ -206,13 +206,21 @@ impl<'a, 'b, 'tcx> visit::Visitor<'tcx> for FnDefVisitor<'a, 'b, 'tcx> {
|
||||||
fn visit_pat(&mut self, pat: &'tcx hir::Pat) {
|
fn visit_pat(&mut self, pat: &'tcx hir::Pat) {
|
||||||
let cx = self.cx;
|
let cx = self.cx;
|
||||||
|
|
||||||
if let hir::PatKind::Binding(hir::BindingMode::BindByValue(_), _, _, _) = pat.node {
|
// We want to detect pattern bindings that move a value onto the stack.
|
||||||
let ty = cx.tables.pat_ty(pat);
|
// When "default binding modes" https://github.com/rust-lang/rust/issues/42640
|
||||||
if is_unrooted_ty(cx, ty, self.in_new_function) {
|
// are implemented, the `Unannotated` case could cause false-positives.
|
||||||
cx.span_lint(UNROOTED_MUST_ROOT,
|
// These should be fixable by adding an explicit `ref`.
|
||||||
pat.span,
|
match pat.node {
|
||||||
&format!("Expression of type {:?} must be rooted", ty))
|
hir::PatKind::Binding(hir::BindingAnnotation::Unannotated, _, _, _) |
|
||||||
|
hir::PatKind::Binding(hir::BindingAnnotation::Mutable, _, _, _) => {
|
||||||
|
let ty = cx.tables.pat_ty(pat);
|
||||||
|
if is_unrooted_ty(cx, ty, self.in_new_function) {
|
||||||
|
cx.span_lint(UNROOTED_MUST_ROOT,
|
||||||
|
pat.span,
|
||||||
|
&format!("Expression of type {:?} must be rooted", ty))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
visit::walk_pat(self, pat);
|
visit::walk_pat(self, pat);
|
||||||
|
|
|
@ -458,7 +458,7 @@ where
|
||||||
/// Matches a complex selector.
|
/// Matches a complex selector.
|
||||||
pub fn matches_complex_selector<E, F>(mut iter: SelectorIter<E::Impl>,
|
pub fn matches_complex_selector<E, F>(mut iter: SelectorIter<E::Impl>,
|
||||||
element: &E,
|
element: &E,
|
||||||
mut context: &mut LocalMatchingContext<E::Impl>,
|
context: &mut LocalMatchingContext<E::Impl>,
|
||||||
flags_setter: &mut F)
|
flags_setter: &mut F)
|
||||||
-> bool
|
-> bool
|
||||||
where E: Element,
|
where E: Element,
|
||||||
|
|
|
@ -1464,7 +1464,7 @@ fn parse_negation<'i, 't, P, E, Impl>(parser: &P,
|
||||||
fn parse_compound_selector<'i, 't, P, E, Impl>(
|
fn parse_compound_selector<'i, 't, P, E, Impl>(
|
||||||
parser: &P,
|
parser: &P,
|
||||||
input: &mut CssParser<'i, 't>,
|
input: &mut CssParser<'i, 't>,
|
||||||
mut builder: &mut SelectorBuilder<Impl>)
|
builder: &mut SelectorBuilder<Impl>)
|
||||||
-> Result<bool, ParseError<'i, SelectorParseError<'i, E>>>
|
-> Result<bool, ParseError<'i, SelectorParseError<'i, E>>>
|
||||||
where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl
|
where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl
|
||||||
{
|
{
|
||||||
|
|
|
@ -154,7 +154,7 @@ impl<'a, 'b: 'a, E> TreeStyleInvalidator<'a, 'b, E>
|
||||||
trace!(" > visitedness change, force subtree restyle");
|
trace!(" > visitedness change, force subtree restyle");
|
||||||
// We can't just return here because there may also be attribute
|
// We can't just return here because there may also be attribute
|
||||||
// changes as well that imply additional hints.
|
// changes as well that imply additional hints.
|
||||||
let mut data = self.data.as_mut().unwrap();
|
let data = self.data.as_mut().unwrap();
|
||||||
data.restyle.hint.insert(RestyleHint::restyle_subtree());
|
data.restyle.hint.insert(RestyleHint::restyle_subtree());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -482,7 +482,7 @@ pub trait MatchMethods : TElement {
|
||||||
fn finish_restyle(
|
fn finish_restyle(
|
||||||
&self,
|
&self,
|
||||||
context: &mut StyleContext<Self>,
|
context: &mut StyleContext<Self>,
|
||||||
mut data: &mut ElementData,
|
data: &mut ElementData,
|
||||||
mut new_styles: ElementStyles,
|
mut new_styles: ElementStyles,
|
||||||
important_rules_changed: bool,
|
important_rules_changed: bool,
|
||||||
) -> ChildCascadeRequirement {
|
) -> ChildCascadeRequirement {
|
||||||
|
|
|
@ -3395,7 +3395,7 @@ pub fn modify_border_style_for_inline_sides(style: &mut Arc<ComputedValues>,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut style = Arc::make_mut(style);
|
let style = Arc::make_mut(style);
|
||||||
let border = Arc::make_mut(&mut style.border);
|
let border = Arc::make_mut(&mut style.border);
|
||||||
match side {
|
match side {
|
||||||
PhysicalSide::Left => {
|
PhysicalSide::Left => {
|
||||||
|
|
|
@ -300,7 +300,7 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
|
||||||
|
|
||||||
if overflow_x != original_overflow_x ||
|
if overflow_x != original_overflow_x ||
|
||||||
overflow_y != original_overflow_y {
|
overflow_y != original_overflow_y {
|
||||||
let mut box_style = self.style.mutate_box();
|
let box_style = self.style.mutate_box();
|
||||||
box_style.set_overflow_x(overflow_x);
|
box_style.set_overflow_x(overflow_x);
|
||||||
box_style.set_overflow_y(overflow_y);
|
box_style.set_overflow_y(overflow_y);
|
||||||
}
|
}
|
||||||
|
|
|
@ -247,7 +247,7 @@ where
|
||||||
Some(&*primary_style.style)
|
Some(&*primary_style.style)
|
||||||
};
|
};
|
||||||
|
|
||||||
for (i, mut inputs) in pseudo_array.iter_mut().enumerate() {
|
for (i, inputs) in pseudo_array.iter_mut().enumerate() {
|
||||||
if let Some(inputs) = inputs.take() {
|
if let Some(inputs) = inputs.take() {
|
||||||
let pseudo = PseudoElement::from_eager_index(i);
|
let pseudo = PseudoElement::from_eager_index(i);
|
||||||
pseudo_styles.set(
|
pseudo_styles.set(
|
||||||
|
|
|
@ -150,7 +150,7 @@ impl CssRulesHelpers for RawOffsetArc<Locked<CssRules>> {
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut write_guard = lock.write();
|
let mut write_guard = lock.write();
|
||||||
let mut rules = self.write_with(&mut write_guard);
|
let rules = self.write_with(&mut write_guard);
|
||||||
// Step 5
|
// Step 5
|
||||||
// Computes the maximum allowed parser state at a given index.
|
// Computes the maximum allowed parser state at a given index.
|
||||||
let rev_state = rules.0.get(index).map_or(State::Body, CssRule::rule_state);
|
let rev_state = rules.0.get(index).map_or(State::Body, CssRule::rule_state);
|
||||||
|
|
|
@ -209,7 +209,7 @@ impl<'a, 'i> AtRuleParser<'i> for TopLevelRuleParser<'a> {
|
||||||
let id = register_namespace(&url)
|
let id = register_namespace(&url)
|
||||||
.map_err(|()| StyleParseError::UnspecifiedError)?;
|
.map_err(|()| StyleParseError::UnspecifiedError)?;
|
||||||
|
|
||||||
let mut namespaces = self.namespaces.as_mut().unwrap();
|
let namespaces = self.namespaces.as_mut().unwrap();
|
||||||
|
|
||||||
let opt_prefix = if let Ok(prefix) = prefix_result {
|
let opt_prefix = if let Ok(prefix) = prefix_result {
|
||||||
let prefix = Prefix::from(prefix.as_ref());
|
let prefix = Prefix::from(prefix.as_ref());
|
||||||
|
|
|
@ -70,7 +70,7 @@ impl<'a, 'b, C> Iterator for RulesIterator<'a, 'b, C>
|
||||||
|
|
||||||
let rule;
|
let rule;
|
||||||
let sub_iter = {
|
let sub_iter = {
|
||||||
let mut nested_iter = self.stack.last_mut().unwrap();
|
let nested_iter = self.stack.last_mut().unwrap();
|
||||||
rule = match nested_iter.next() {
|
rule = match nested_iter.next() {
|
||||||
Some(r) => r,
|
Some(r) => r,
|
||||||
None => {
|
None => {
|
||||||
|
|
|
@ -208,7 +208,7 @@ impl ComputeSquaredDistance for Color {
|
||||||
impl ToAnimatedZero for Color {
|
impl ToAnimatedZero for Color {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_animated_zero(&self) -> Result<Self, ()> {
|
fn to_animated_zero(&self) -> Result<Self, ()> {
|
||||||
/// FIXME(nox): This does not look correct to me.
|
// FIXME(nox): This does not look correct to me.
|
||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ impl BorderImageSideWidth {
|
||||||
impl ToAnimatedZero for BorderCornerRadius {
|
impl ToAnimatedZero for BorderCornerRadius {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_animated_zero(&self) -> Result<Self, ()> {
|
fn to_animated_zero(&self) -> Result<Self, ()> {
|
||||||
/// FIXME(nox): Why?
|
// FIXME(nox): Why?
|
||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -702,7 +702,7 @@ impl Handler {
|
||||||
fn handle_set_timeouts(&mut self,
|
fn handle_set_timeouts(&mut self,
|
||||||
parameters: &TimeoutsParameters)
|
parameters: &TimeoutsParameters)
|
||||||
-> WebDriverResult<WebDriverResponse> {
|
-> WebDriverResult<WebDriverResponse> {
|
||||||
let mut session = self.session
|
let session = self.session
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.ok_or(WebDriverError::new(ErrorStatus::SessionNotCreated, ""))?;
|
.ok_or(WebDriverError::new(ErrorStatus::SessionNotCreated, ""))?;
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
599be0d18f4c6ddf36366d2a5a2ca6dc65886896
|
13d94d5fa8129a34f5c77a1bcd76983f5aed2434
|
||||||
|
|
|
@ -50,19 +50,6 @@ fn get_mock_rules(css_selectors: &[&str]) -> (Vec<Vec<Rule>>, SharedRwLock) {
|
||||||
}).collect(), shared_lock)
|
}).collect(), shared_lock)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_mock_map(selectors: &[&str]) -> (SelectorMap<Rule>, SharedRwLock) {
|
|
||||||
let mut map = SelectorMap::<Rule>::new();
|
|
||||||
let (selector_rules, shared_lock) = get_mock_rules(selectors);
|
|
||||||
|
|
||||||
for rules in selector_rules.into_iter() {
|
|
||||||
for rule in rules.into_iter() {
|
|
||||||
map.insert(rule, QuirksMode::NoQuirks)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
(map, shared_lock)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_selectors(selectors: &[&str]) -> Vec<Selector<SelectorImpl>> {
|
fn parse_selectors(selectors: &[&str]) -> Vec<Selector<SelectorImpl>> {
|
||||||
selectors.iter()
|
selectors.iter()
|
||||||
.map(|x| SelectorParser::parse_author_origin_no_namespace(x).unwrap().0
|
.map(|x| SelectorParser::parse_author_origin_no_namespace(x).unwrap().0
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue