aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbors-servo <metajack+bors@gmail.com>2015-04-14 00:10:08 -0500
committerbors-servo <metajack+bors@gmail.com>2015-04-14 00:10:08 -0500
commit4fac8b6810d9d748fffc025cfd1bb1d2b6c5655d (patch)
tree4e5f039f95c904475455d776153334c512f061f3
parent55de52d76ad0c864b7875c561df5c5f3867b2d73 (diff)
parent7a65b95ae5c847f5a6dbb650865ca6d14490e9bc (diff)
downloadservo-4fac8b6810d9d748fffc025cfd1bb1d2b6c5655d.tar.gz
servo-4fac8b6810d9d748fffc025cfd1bb1d2b6c5655d.zip
Auto merge of #5593 - shinglyu:ismap, r=jdm
This implements issue 4873
-rw-r--r--components/layout/layout_task.rs23
-rw-r--r--components/script/dom/activation.rs4
-rw-r--r--components/script/dom/element.rs2
-rw-r--r--components/script/dom/htmlanchorelement.rs34
-rw-r--r--components/script/dom/htmlbuttonelement.rs3
-rw-r--r--components/script/dom/htmlinputelement.rs2
-rw-r--r--tests/html/test_img_ismap.html17
7 files changed, 65 insertions, 20 deletions
diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs
index 39ac8956cb6..c31fbb0bab9 100644
--- a/components/layout/layout_task.rs
+++ b/components/layout/layout_task.rs
@@ -10,6 +10,7 @@
use animation;
use construct::ConstructionResult;
use context::{SharedLayoutContext, SharedLayoutContextWrapper};
+use css::node_style::StyledNode;
use display_list_builder::ToGfxColor;
use flow::{self, Flow, ImmutableFlowUtils, MutableFlowUtils, MutableOwnedFlowUtils};
use flow_ref::FlowRef;
@@ -713,7 +714,10 @@ impl LayoutTask {
let requested_node: OpaqueNode = OpaqueNodeMethods::from_script_node(requested_node);
let mut iterator = UnioningFragmentBorderBoxIterator::new(requested_node);
sequential::iterate_through_flow_tree_fragment_border_boxes(layout_root, &mut iterator);
- rw_data.content_box_response = iterator.rect;
+ rw_data.content_box_response = match iterator.rect {
+ Some(rect) => rect,
+ None => Rect::zero()
+ };
}
fn process_content_boxes_request<'a>(&'a self,
@@ -1158,25 +1162,28 @@ impl LayoutRPC for LayoutRPCImpl {
struct UnioningFragmentBorderBoxIterator {
node_address: OpaqueNode,
- rect: Rect<Au>,
+ rect: Option<Rect<Au>>,
}
impl UnioningFragmentBorderBoxIterator {
fn new(node_address: OpaqueNode) -> UnioningFragmentBorderBoxIterator {
UnioningFragmentBorderBoxIterator {
node_address: node_address,
- rect: Rect::zero(),
+ rect: None
}
}
}
impl FragmentBorderBoxIterator for UnioningFragmentBorderBoxIterator {
fn process(&mut self, _: &Fragment, border_box: &Rect<Au>) {
- self.rect = if self.rect.is_empty() {
- *border_box
- } else {
- self.rect.union(border_box)
- }
+ self.rect = match self.rect {
+ Some(rect) => {
+ Some(rect.union(border_box))
+ }
+ None => {
+ Some(*border_box)
+ }
+ };
}
fn should_process(&mut self, fragment: &Fragment) -> bool {
diff --git a/components/script/dom/activation.rs b/components/script/dom/activation.rs
index 46ca27cabb5..c95969729b1 100644
--- a/components/script/dom/activation.rs
+++ b/components/script/dom/activation.rs
@@ -27,7 +27,7 @@ pub trait Activatable : Copy {
fn canceled_activation(&self);
// https://html.spec.whatwg.org/multipage/interaction.html#run-post-click-activation-steps
- fn activation_behavior(&self);
+ fn activation_behavior(&self, event: JSRef<Event>, target: JSRef<EventTarget>);
// https://html.spec.whatwg.org/multipage/forms.html#implicit-submission
fn implicit_submission(&self, ctrlKey: bool, shiftKey: bool, altKey: bool, metaKey: bool);
@@ -60,7 +60,7 @@ pub trait Activatable : Copy {
self.canceled_activation();
} else {
// post click activation
- self.activation_behavior();
+ self.activation_behavior(event, target);
}
// Step 6
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs
index 523caf59a92..d7c7e1908cb 100644
--- a/components/script/dom/element.rs
+++ b/components/script/dom/element.rs
@@ -1675,7 +1675,7 @@ impl<'a> ActivationElementHelpers<'a> for JSRef<'a, Element> {
event.fire(target);
if !event.DefaultPrevented() {
// post click activation
- elem.activation_behavior();
+ elem.activation_behavior(event, target);
} else {
elem.canceled_activation();
}
diff --git a/components/script/dom/htmlanchorelement.rs b/components/script/dom/htmlanchorelement.rs
index 1219692cd9b..a4da4a148d6 100644
--- a/components/script/dom/htmlanchorelement.rs
+++ b/components/script/dom/htmlanchorelement.rs
@@ -2,14 +2,17 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
use dom::activation::Activatable;
use dom::attr::AttrValue;
use dom::bindings::codegen::Bindings::AttrBinding::AttrMethods;
use dom::bindings::codegen::Bindings::HTMLAnchorElementBinding;
use dom::bindings::codegen::Bindings::HTMLAnchorElementBinding::HTMLAnchorElementMethods;
+use dom::bindings::codegen::Bindings::MouseEventBinding::MouseEventMethods;
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
-use dom::bindings::codegen::InheritTypes::HTMLAnchorElementDerived;
-use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast, NodeCast};
+use dom::bindings::codegen::InheritTypes::{HTMLAnchorElementDerived, HTMLImageElementDerived};
+use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast};
+use dom::bindings::codegen::InheritTypes::{MouseEventCast, NodeCast};
use dom::bindings::js::{MutNullableJS, JSRef, Temporary, OptionalRootable};
use dom::document::{Document, DocumentHelpers};
use dom::domtokenlist::DOMTokenList;
@@ -17,10 +20,12 @@ use dom::element::{Element, AttributeHandlers, ElementTypeId};
use dom::event::Event;
use dom::eventtarget::{EventTarget, EventTargetTypeId};
use dom::htmlelement::{HTMLElement, HTMLElementTypeId};
-use dom::node::{Node, NodeHelpers, NodeTypeId, document_from_node};
+use dom::node::{Node, NodeHelpers, NodeTypeId, document_from_node, window_from_node};
use dom::virtualmethods::VirtualMethods;
+use dom::window::WindowHelpers;
use std::default::Default;
+use std::num::ToPrimitive;
use string_cache::Atom;
use util::str::DOMString;
@@ -112,20 +117,35 @@ impl<'a> Activatable for JSRef<'a, HTMLAnchorElement> {
}
//https://html.spec.whatwg.org/multipage/semantics.html#the-a-element:activation-behaviour
- fn activation_behavior(&self) {
+ fn activation_behavior(&self, event: JSRef<Event>, target: JSRef<EventTarget>) {
//Step 1. If the node document is not fully active, abort.
let doc = document_from_node(*self).root();
if !doc.r().is_fully_active() {
return;
}
//TODO: Step 2. Check if browsing context is specified and act accordingly.
- //TODO: Step 3. Handle <img ismap/>.
- //TODO: Step 4. Download the link is `download` attribute is set.
+ //Step 3. Handle <img ismap/>.
let element: JSRef<Element> = ElementCast::from_ref(*self);
+ let mouse_event = MouseEventCast::to_ref(event).unwrap();
+ let mut ismap_suffix = None;
+ if let Some(element) = ElementCast::to_ref(target) {
+ if target.is_htmlimageelement() && element.has_attribute(&atom!("ismap")) {
+
+ let target_node = NodeCast::to_ref(target).unwrap();
+ let rect = window_from_node(target_node).root().r().content_box_query(target_node.to_trusted_node_address());
+ ismap_suffix = Some(
+ format!("?{},{}", mouse_event.ClientX().to_f32().unwrap() - rect.origin.x.to_frac32_px(),
+ mouse_event.ClientY().to_f32().unwrap() - rect.origin.y.to_frac32_px())
+ )
+ }
+ }
+
+ //TODO: Step 4. Download the link is `download` attribute is set.
+
let attr = element.get_attribute(&ns!(""), &atom!("href")).root();
match attr {
Some(ref href) => {
- let value = href.r().Value();
+ let value = href.r().Value() + ismap_suffix.as_ref().map(|s| &**s).unwrap_or("");
debug!("clicked on link to {}", value);
doc.r().load_anchor_href(value);
}
diff --git a/components/script/dom/htmlbuttonelement.rs b/components/script/dom/htmlbuttonelement.rs
index a4877e72aa4..b79c966d993 100644
--- a/components/script/dom/htmlbuttonelement.rs
+++ b/components/script/dom/htmlbuttonelement.rs
@@ -13,6 +13,7 @@ use dom::bindings::js::{JSRef, Temporary};
use dom::document::Document;
use dom::element::{AttributeHandlers, Element, ElementTypeId};
use dom::element::ActivationElementHelpers;
+use dom::event::Event;
use dom::eventtarget::{EventTarget, EventTargetTypeId};
use dom::htmlelement::{HTMLElement, HTMLElementTypeId};
use dom::htmlformelement::{FormSubmitter, FormControl, HTMLFormElementHelpers};
@@ -196,7 +197,7 @@ impl<'a> Activatable for JSRef<'a, HTMLButtonElement> {
}
// https://html.spec.whatwg.org/multipage/interaction.html#run-post-click-activation-steps
- fn activation_behavior(&self) {
+ fn activation_behavior(&self, _event: JSRef<Event>, _target: JSRef<EventTarget>) {
let ty = self.button_type.get();
match ty {
//https://html.spec.whatwg.org/multipage/forms.html#attr-button-type-submit-state
diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs
index 30cd0676eb1..5bd170ebea7 100644
--- a/components/script/dom/htmlinputelement.rs
+++ b/components/script/dom/htmlinputelement.rs
@@ -753,7 +753,7 @@ impl<'a> Activatable for JSRef<'a, HTMLInputElement> {
}
// https://html.spec.whatwg.org/multipage/interaction.html#run-post-click-activation-steps
- fn activation_behavior(&self) {
+ fn activation_behavior(&self, _event: JSRef<Event>, _target: JSRef<EventTarget>) {
let ty = self.input_type.get();
if self.activation_state.borrow().old_type != ty {
// Type changed, abandon ship
diff --git a/tests/html/test_img_ismap.html b/tests/html/test_img_ismap.html
new file mode 100644
index 00000000000..669a941d07d
--- /dev/null
+++ b/tests/html/test_img_ismap.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>img element ismap activation test</title>
+ </head>
+ <body>
+ <p>Click my nose to get the coordinates!</p>
+ <a href="test_img_ismap.html">
+ <img src="andreas.jpeg" alt="andreas" ismap/>
+ </a>
+ <p>Nothing happends if you click my nose</p>
+ <a href="test_img_ismap.html">
+ <img src="andreas.jpeg" alt="andreas"/>
+ </a>
+ </body>
+</html>