HTML image map support

This commit is contained in:
bachar 2016-12-01 21:23:22 -05:00 committed by Manish Goregaokar
parent c784bc6944
commit 980dde7e15
7 changed files with 463 additions and 2 deletions

View file

@ -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) {