From f4a2afc3a6b6f530685608501c3ff0d57cc05bcb Mon Sep 17 00:00:00 2001 From: Shing Lyu Date: Tue, 27 Jan 2015 22:00:25 +0800 Subject: [PATCH] Bug 4236: Moved anchorelement click event to activation behaviour --- components/script/dom/element.rs | 23 ++++--- components/script/dom/htmlanchorelement.rs | 71 ++++++++++++++-------- 2 files changed, 61 insertions(+), 33 deletions(-) diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index ad1e70b30d1..e54607f73a0 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -21,6 +21,7 @@ use dom::bindings::codegen::InheritTypes::{HTMLInputElementDerived, HTMLTableEle use dom::bindings::codegen::InheritTypes::{HTMLTableElementDerived, HTMLTableCellElementDerived}; use dom::bindings::codegen::InheritTypes::{HTMLTableRowElementDerived, HTMLTextAreaElementDerived}; use dom::bindings::codegen::InheritTypes::{HTMLTableSectionElementDerived, NodeCast}; +use dom::bindings::codegen::InheritTypes::HTMLAnchorElementCast; use dom::bindings::error::{ErrorResult, Fallible}; use dom::bindings::error::Error::{NamespaceError, InvalidCharacter, Syntax}; use dom::bindings::js::{MutNullableJS, JS, JSRef, LayoutJS, Temporary, TemporaryPushable}; @@ -34,6 +35,7 @@ use dom::document::{Document, DocumentHelpers, LayoutDocumentHelpers}; use dom::domtokenlist::DOMTokenList; use dom::event::{Event, EventHelpers}; use dom::eventtarget::{EventTarget, EventTargetTypeId}; +use dom::htmlanchorelement::HTMLAnchorElement; use dom::htmlbodyelement::{HTMLBodyElement, HTMLBodyElementHelpers}; use dom::htmlcollection::HTMLCollection; use dom::htmlelement::HTMLElementTypeId; @@ -1446,19 +1448,26 @@ pub trait ActivationElementHelpers<'a> { impl<'a> ActivationElementHelpers<'a> for JSRef<'a, Element> { fn as_maybe_activatable(&'a self) -> Option<&'a (Activatable + 'a)> { let node: JSRef = NodeCast::from_ref(*self); - match node.type_id() { + let element = match node.type_id() { NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLInputElement)) => { let element: &'a JSRef<'a, HTMLInputElement> = HTMLInputElementCast::to_borrowed_ref(self).unwrap(); - if element.is_instance_activatable() { - Some(element as &'a (Activatable + 'a)) - } else { - None - } + Some(element as &'a (Activatable + 'a)) + }, + NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAnchorElement)) => { + let element: &'a JSRef<'a, HTMLAnchorElement> = HTMLAnchorElementCast::to_borrowed_ref(self).unwrap(); + Some(element as &'a (Activatable + 'a)) }, _ => { None } - } + }; + element.and_then(|elem| { + if elem.is_instance_activatable() { + Some(elem) + } else { + None + } + }) } fn click_in_progress(self) -> bool { diff --git a/components/script/dom/htmlanchorelement.rs b/components/script/dom/htmlanchorelement.rs index 775db1e2852..8d427528aba 100644 --- a/components/script/dom/htmlanchorelement.rs +++ b/components/script/dom/htmlanchorelement.rs @@ -2,9 +2,9 @@ * 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::EventBinding::EventMethods; use dom::bindings::codegen::Bindings::HTMLAnchorElementBinding; use dom::bindings::codegen::Bindings::HTMLAnchorElementBinding::HTMLAnchorElementMethods; use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; @@ -17,7 +17,7 @@ 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}; +use dom::node::{Node, NodeHelpers, NodeTypeId, document_from_node}; use dom::virtualmethods::VirtualMethods; use std::default::Default; @@ -51,29 +51,6 @@ impl HTMLAnchorElement { } } -trait PrivateHTMLAnchorElementHelpers { - fn handle_event_impl(self, event: JSRef); -} - -impl<'a> PrivateHTMLAnchorElementHelpers for JSRef<'a, HTMLAnchorElement> { - fn handle_event_impl(self, event: JSRef) { - if "click" == event.Type().as_slice() && !event.DefaultPrevented() { - let element: JSRef = ElementCast::from_ref(self); - let attr = element.get_attribute(ns!(""), &atom!("href")).root(); - match attr { - Some(ref href) => { - let value = href.r().Value(); - debug!("clicked on link to {}", value); - let node: JSRef = NodeCast::from_ref(self); - let doc = node.owner_doc().root(); - doc.r().load_anchor_href(value); - } - None => () - } - } - } -} - impl<'a> VirtualMethods for JSRef<'a, HTMLAnchorElement> { fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { let htmlelement: &JSRef = HTMLElementCast::from_borrowed_ref(self); @@ -87,7 +64,6 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLAnchorElement> { } None => {} } - self.handle_event_impl(event); } fn parse_plain_attribute(&self, name: &Atom, value: DOMString) -> AttrValue { @@ -115,3 +91,46 @@ impl<'a> HTMLAnchorElementMethods for JSRef<'a, HTMLAnchorElement> { }) } } + +impl<'a> Activatable for JSRef<'a, HTMLAnchorElement> { + fn as_element(&self) -> Temporary { + Temporary::from_rooted(ElementCast::from_ref(*self)) + } + + fn is_instance_activatable(&self) -> bool { + true + } + + + //TODO:https://html.spec.whatwg.org/multipage/semantics.html#the-a-element + fn pre_click_activation(&self) { + } + + //TODO:https://html.spec.whatwg.org/multipage/semantics.html#the-a-element + // https://html.spec.whatwg.org/multipage/interaction.html#run-canceled-activation-steps + fn canceled_activation(&self) { + } + + //https://html.spec.whatwg.org/multipage/semantics.html#the-a-element:activation-behaviour + fn activation_behavior(&self) { + //TODO: Step 1. If the node document is not fully active, abort. + //TODO: Step 2. Check if browsing context is specified and act accordingly. + //TODO: Step 3. Handle . + //TODO: Step 4. Download the link is `download` attribute is set. + let element: JSRef = ElementCast::from_ref(*self); + let attr = element.get_attribute(ns!(""), &atom!("href")).root(); + match attr { + Some(ref href) => { + let value = href.r().Value(); + debug!("clicked on link to {}", value); + let doc = document_from_node(*self).root(); + doc.r().load_anchor_href(value); + } + None => () + } + } + + //TODO:https://html.spec.whatwg.org/multipage/semantics.html#the-a-element + fn implicit_submission(&self, _ctrlKey: bool, _shiftKey: bool, _altKey: bool, _metaKey: bool) { + } +}