mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
HTML image map support
This commit is contained in:
parent
c784bc6944
commit
980dde7e15
7 changed files with 463 additions and 2 deletions
|
@ -3,10 +3,14 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use app_units::{Au, AU_PER_PX};
|
||||
use dom::activation::Activatable;
|
||||
use dom::attr::Attr;
|
||||
use dom::bindings::cell::DOMRefCell;
|
||||
use dom::bindings::codegen::Bindings::DOMRectBinding::DOMRectBinding::DOMRectMethods;
|
||||
use dom::bindings::codegen::Bindings::ElementBinding::ElementBinding::ElementMethods;
|
||||
use dom::bindings::codegen::Bindings::HTMLImageElementBinding;
|
||||
use dom::bindings::codegen::Bindings::HTMLImageElementBinding::HTMLImageElementMethods;
|
||||
use dom::bindings::codegen::Bindings::MouseEventBinding::MouseEventMethods;
|
||||
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
|
||||
use dom::bindings::error::Fallible;
|
||||
use dom::bindings::inheritance::Castable;
|
||||
|
@ -15,17 +19,23 @@ use dom::bindings::refcounted::Trusted;
|
|||
use dom::bindings::str::DOMString;
|
||||
use dom::document::Document;
|
||||
use dom::element::{AttributeMutation, Element, RawLayoutElementHelpers};
|
||||
use dom::event::Event;
|
||||
use dom::eventtarget::EventTarget;
|
||||
use dom::htmlareaelement::HTMLAreaElement;
|
||||
use dom::htmlelement::HTMLElement;
|
||||
use dom::htmlmapelement::HTMLMapElement;
|
||||
use dom::mouseevent::MouseEvent;
|
||||
use dom::node::{Node, NodeDamage, document_from_node, window_from_node};
|
||||
use dom::values::UNSIGNED_LONG_MAX;
|
||||
use dom::virtualmethods::VirtualMethods;
|
||||
use dom::window::Window;
|
||||
use euclid::point::Point2D;
|
||||
use html5ever_atoms::LocalName;
|
||||
use ipc_channel::ipc;
|
||||
use ipc_channel::router::ROUTER;
|
||||
use net_traits::image::base::{Image, ImageMetadata};
|
||||
use net_traits::image_cache_thread::{ImageResponder, ImageResponse};
|
||||
use num_traits::ToPrimitive;
|
||||
use script_thread::Runnable;
|
||||
use servo_url::ServoUrl;
|
||||
use std::i32;
|
||||
|
@ -234,6 +244,38 @@ impl HTMLImageElement {
|
|||
|
||||
Ok(image)
|
||||
}
|
||||
pub fn areas(&self) -> Option<Vec<Root<HTMLAreaElement>>> {
|
||||
let elem = self.upcast::<Element>();
|
||||
let usemap_attr;
|
||||
if elem.has_attribute(&LocalName::from("usemap")) {
|
||||
usemap_attr = elem.get_string_attribute(&local_name!("usemap"));
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
|
||||
let (first, last) = usemap_attr.split_at(1);
|
||||
|
||||
match first {
|
||||
"#" => {},
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
match last.len() {
|
||||
0 => return None,
|
||||
_ => {},
|
||||
};
|
||||
|
||||
let map = self.upcast::<Node>()
|
||||
.following_siblings()
|
||||
.filter_map(Root::downcast::<HTMLMapElement>)
|
||||
.find(|n| n.upcast::<Element>().get_string_attribute(&LocalName::from("name")) == last);
|
||||
|
||||
let elements: Vec<Root<HTMLAreaElement>> = map.unwrap().upcast::<Node>()
|
||||
.children()
|
||||
.filter_map(Root::downcast::<HTMLAreaElement>)
|
||||
.collect();
|
||||
Some(elements)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait LayoutHTMLImageElementHelpers {
|
||||
|
@ -429,6 +471,43 @@ impl VirtualMethods for HTMLImageElement {
|
|||
_ => self.super_type().unwrap().parse_plain_attribute(name, value),
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_event(&self, event: &Event) {
|
||||
if (event.type_() == atom!("click")) {
|
||||
let area_elements = self.areas();
|
||||
let elements = if let Some(x) = area_elements {
|
||||
x
|
||||
} else {
|
||||
return
|
||||
};
|
||||
|
||||
// Fetch click coordinates
|
||||
let mouse_event = if let Some(x) = event.downcast::<MouseEvent>() {
|
||||
x
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
|
||||
let point = Point2D::new(mouse_event.ClientX().to_f32().unwrap(), mouse_event.ClientY().to_f32().unwrap());
|
||||
// Walk HTMLAreaElements
|
||||
let mut index = 0;
|
||||
while index < elements.len() {
|
||||
let shape = elements[index].get_shape_from_coords();
|
||||
let p = Point2D::new(self.upcast::<Element>().GetBoundingClientRect().X() as f32,
|
||||
self.upcast::<Element>().GetBoundingClientRect().Y() as f32);
|
||||
let shp = if let Some(x) = shape {
|
||||
x.absolute_coords(p)
|
||||
} else {
|
||||
return
|
||||
};
|
||||
if shp.hit_test(point) {
|
||||
elements[index].activation_behavior(event, self.upcast());
|
||||
return
|
||||
}
|
||||
index += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn image_dimension_setter(element: &Element, attr: LocalName, value: u32) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue