mirror of
https://github.com/servo/servo.git
synced 2025-07-23 07:13:52 +01:00
Auto merge of #9030 - askobara:refactoring-add-htmlformelement-fire_event, r=Manishearth
Add helper method HTMLFormElement::fire_event Fixes #8777 <!-- Reviewable:start --> [<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/9030) <!-- Reviewable:end -->
This commit is contained in:
commit
dafdc856ac
8 changed files with 61 additions and 71 deletions
|
@ -558,12 +558,8 @@ impl Document {
|
||||||
|
|
||||||
self.ready_state.set(state);
|
self.ready_state.set(state);
|
||||||
|
|
||||||
let event = Event::new(GlobalRef::Window(&self.window),
|
self.upcast::<EventTarget>().fire_simple_event("readystatechange",
|
||||||
atom!("readystatechange"),
|
GlobalRef::Window(&self.window));
|
||||||
EventBubbles::DoesNotBubble,
|
|
||||||
EventCancelable::NotCancelable);
|
|
||||||
let target = self.upcast::<EventTarget>();
|
|
||||||
let _ = event.fire(target);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return whether scripting is enabled or not
|
/// Return whether scripting is enabled or not
|
||||||
|
|
|
@ -11,12 +11,12 @@ use dom::bindings::codegen::Bindings::EventListenerBinding::EventListener;
|
||||||
use dom::bindings::codegen::Bindings::EventTargetBinding::EventTargetMethods;
|
use dom::bindings::codegen::Bindings::EventTargetBinding::EventTargetMethods;
|
||||||
use dom::bindings::codegen::UnionTypes::EventOrString;
|
use dom::bindings::codegen::UnionTypes::EventOrString;
|
||||||
use dom::bindings::error::{Error, Fallible, report_pending_exception};
|
use dom::bindings::error::{Error, Fallible, report_pending_exception};
|
||||||
use dom::bindings::global::global_root_from_reflector;
|
use dom::bindings::global::{GlobalRef, global_root_from_reflector};
|
||||||
use dom::bindings::inheritance::{Castable, EventTargetTypeId};
|
use dom::bindings::inheritance::{Castable, EventTargetTypeId};
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::reflector::{Reflectable, Reflector};
|
use dom::bindings::reflector::{Reflectable, Reflector};
|
||||||
use dom::errorevent::ErrorEvent;
|
use dom::errorevent::ErrorEvent;
|
||||||
use dom::event::Event;
|
use dom::event::{Event, EventBubbles, EventCancelable};
|
||||||
use dom::eventdispatcher::dispatch_event;
|
use dom::eventdispatcher::dispatch_event;
|
||||||
use dom::virtualmethods::VirtualMethods;
|
use dom::virtualmethods::VirtualMethods;
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
|
@ -329,6 +329,24 @@ impl EventTarget {
|
||||||
pub fn has_handlers(&self) -> bool {
|
pub fn has_handlers(&self) -> bool {
|
||||||
!self.handlers.borrow().is_empty()
|
!self.handlers.borrow().is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Implements https://html.spec.whatwg.org/multipage/#fire-a-simple-event
|
||||||
|
pub fn fire_simple_event(&self, name: &str, win: GlobalRef) -> Root<Event> {
|
||||||
|
self.fire_simple_event_params(name, EventBubbles::DoesNotBubble,
|
||||||
|
EventCancelable::NotCancelable, win)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Implements more customizable variant of EventTarget::fire_simple_event.
|
||||||
|
pub fn fire_simple_event_params(&self, name: &str,
|
||||||
|
bubbles: EventBubbles,
|
||||||
|
cancelable: EventCancelable,
|
||||||
|
win: GlobalRef) -> Root<Event> {
|
||||||
|
let event = Event::new(win, Atom::from(name), bubbles, cancelable);
|
||||||
|
|
||||||
|
event.fire(self);
|
||||||
|
|
||||||
|
event
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventTargetMethods for EventTarget {
|
impl EventTargetMethods for EventTarget {
|
||||||
|
|
|
@ -16,7 +16,7 @@ use dom::bindings::js::{Root};
|
||||||
use dom::bindings::reflector::Reflectable;
|
use dom::bindings::reflector::Reflectable;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::Element;
|
use dom::element::Element;
|
||||||
use dom::event::{Event, EventBubbles, EventCancelable};
|
use dom::event::{EventBubbles, EventCancelable};
|
||||||
use dom::eventtarget::EventTarget;
|
use dom::eventtarget::EventTarget;
|
||||||
use dom::htmlbuttonelement::HTMLButtonElement;
|
use dom::htmlbuttonelement::HTMLButtonElement;
|
||||||
use dom::htmldatalistelement::HTMLDataListElement;
|
use dom::htmldatalistelement::HTMLDataListElement;
|
||||||
|
@ -169,23 +169,18 @@ impl HTMLFormElement {
|
||||||
{
|
{
|
||||||
if self.interactive_validation().is_err() {
|
if self.interactive_validation().is_err() {
|
||||||
// TODO: Implement event handlers on all form control elements
|
// TODO: Implement event handlers on all form control elements
|
||||||
// XXXKiChjang: We're also calling the following two statements quite often,
|
self.upcast::<EventTarget>()
|
||||||
// we should refactor it into a function
|
.fire_simple_event("invalid", GlobalRef::Window(win.r()));
|
||||||
let event = Event::new(GlobalRef::Window(win.r()),
|
|
||||||
atom!("invalid"),
|
|
||||||
EventBubbles::DoesNotBubble,
|
|
||||||
EventCancelable::NotCancelable);
|
|
||||||
event.fire(self.upcast());
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Step 5
|
// Step 5
|
||||||
if submit_method_flag == SubmittedFrom::NotFromFormSubmitMethod {
|
if submit_method_flag == SubmittedFrom::NotFromFormSubmitMethod {
|
||||||
let event = Event::new(GlobalRef::Window(win.r()),
|
let event = self.upcast::<EventTarget>()
|
||||||
atom!("submit"),
|
.fire_simple_event_params("submit",
|
||||||
EventBubbles::Bubbles,
|
EventBubbles::Bubbles,
|
||||||
EventCancelable::Cancelable);
|
EventCancelable::Cancelable,
|
||||||
event.fire(self.upcast());
|
GlobalRef::Window(win.r()));
|
||||||
if event.DefaultPrevented() {
|
if event.DefaultPrevented() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -280,11 +275,11 @@ impl HTMLFormElement {
|
||||||
// Step 5-6
|
// Step 5-6
|
||||||
let win = window_from_node(self);
|
let win = window_from_node(self);
|
||||||
let unhandled_invalid_controls = invalid_controls.into_iter().filter_map(|field| {
|
let unhandled_invalid_controls = invalid_controls.into_iter().filter_map(|field| {
|
||||||
let event = Event::new(GlobalRef::Window(win.r()),
|
let event = field.as_event_target()
|
||||||
atom!("invalid"),
|
.fire_simple_event_params("invalid",
|
||||||
EventBubbles::DoesNotBubble,
|
EventBubbles::DoesNotBubble,
|
||||||
EventCancelable::Cancelable);
|
EventCancelable::Cancelable,
|
||||||
event.fire(field.as_event_target());
|
GlobalRef::Window(win.r()));
|
||||||
if !event.DefaultPrevented() { return Some(field); }
|
if !event.DefaultPrevented() { return Some(field); }
|
||||||
None
|
None
|
||||||
}).collect::<Vec<FormSubmittableElement>>();
|
}).collect::<Vec<FormSubmittableElement>>();
|
||||||
|
@ -393,11 +388,11 @@ impl HTMLFormElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
let win = window_from_node(self);
|
let win = window_from_node(self);
|
||||||
let event = Event::new(GlobalRef::Window(win.r()),
|
let event = self.upcast::<EventTarget>()
|
||||||
atom!("reset"),
|
.fire_simple_event_params("reset",
|
||||||
EventBubbles::Bubbles,
|
EventBubbles::Bubbles,
|
||||||
EventCancelable::Cancelable);
|
EventCancelable::Cancelable,
|
||||||
event.fire(self.upcast());
|
GlobalRef::Window(win.r()));
|
||||||
if event.DefaultPrevented() {
|
if event.DefaultPrevented() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -430,6 +425,7 @@ impl HTMLFormElement {
|
||||||
};
|
};
|
||||||
self.marked_for_reset.set(false);
|
self.marked_for_reset.set(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: add file support
|
// TODO: add file support
|
||||||
|
|
|
@ -17,7 +17,8 @@ use dom::bindings::reflector::Reflectable;
|
||||||
use dom::customevent::CustomEvent;
|
use dom::customevent::CustomEvent;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::{AttributeMutation, Element, RawLayoutElementHelpers};
|
use dom::element::{AttributeMutation, Element, RawLayoutElementHelpers};
|
||||||
use dom::event::{Event, EventBubbles, EventCancelable};
|
use dom::event::Event;
|
||||||
|
use dom::eventtarget::EventTarget;
|
||||||
use dom::htmlelement::HTMLElement;
|
use dom::htmlelement::HTMLElement;
|
||||||
use dom::node::{Node, window_from_node};
|
use dom::node::{Node, window_from_node};
|
||||||
use dom::urlhelper::UrlHelper;
|
use dom::urlhelper::UrlHelper;
|
||||||
|
@ -208,12 +209,7 @@ impl HTMLIFrameElement {
|
||||||
|
|
||||||
// Step 4
|
// Step 4
|
||||||
let window = window_from_node(self);
|
let window = window_from_node(self);
|
||||||
let event = Event::new(GlobalRef::Window(window.r()),
|
self.upcast::<EventTarget>().fire_simple_event("load", GlobalRef::Window(window.r()));
|
||||||
atom!("load"),
|
|
||||||
EventBubbles::DoesNotBubble,
|
|
||||||
EventCancelable::NotCancelable);
|
|
||||||
event.fire(self.upcast());
|
|
||||||
|
|
||||||
// TODO Step 5 - unset child document `mut iframe load` flag
|
// TODO Step 5 - unset child document `mut iframe load` flag
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ use dom::bindings::js::{LayoutJS, Root};
|
||||||
use dom::bindings::refcounted::Trusted;
|
use dom::bindings::refcounted::Trusted;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::AttributeMutation;
|
use dom::element::AttributeMutation;
|
||||||
use dom::event::{Event, EventBubbles, EventCancelable};
|
use dom::eventtarget::EventTarget;
|
||||||
use dom::htmlelement::HTMLElement;
|
use dom::htmlelement::HTMLElement;
|
||||||
use dom::node::{Node, NodeDamage, document_from_node, window_from_node};
|
use dom::node::{Node, NodeDamage, document_from_node, window_from_node};
|
||||||
use dom::virtualmethods::VirtualMethods;
|
use dom::virtualmethods::VirtualMethods;
|
||||||
|
@ -77,12 +77,7 @@ impl Runnable for ImageResponseHandlerRunnable {
|
||||||
|
|
||||||
// Fire image.onload
|
// Fire image.onload
|
||||||
let window = window_from_node(document.r());
|
let window = window_from_node(document.r());
|
||||||
let event = Event::new(GlobalRef::Window(window.r()),
|
element.upcast::<EventTarget>().fire_simple_event("load", GlobalRef::Window(window.r()));
|
||||||
atom!("load"),
|
|
||||||
EventBubbles::DoesNotBubble,
|
|
||||||
EventCancelable::NotCancelable);
|
|
||||||
event.fire(element.upcast());
|
|
||||||
|
|
||||||
// Trigger reflow
|
// Trigger reflow
|
||||||
window.add_pending_reflow();
|
window.add_pending_reflow();
|
||||||
}
|
}
|
||||||
|
|
|
@ -858,19 +858,16 @@ impl Activatable for HTMLInputElement {
|
||||||
// https://html.spec.whatwg.org/multipage/#radio-button-state-(type=radio):activation-behavior
|
// https://html.spec.whatwg.org/multipage/#radio-button-state-(type=radio):activation-behavior
|
||||||
if self.mutable() {
|
if self.mutable() {
|
||||||
let win = window_from_node(self);
|
let win = window_from_node(self);
|
||||||
let target = self.upcast();
|
let target = self.upcast::<EventTarget>();
|
||||||
|
|
||||||
let event = Event::new(GlobalRef::Window(win.r()),
|
target.fire_simple_event_params("input",
|
||||||
atom!("input"),
|
EventBubbles::Bubbles,
|
||||||
EventBubbles::Bubbles,
|
EventCancelable::NotCancelable,
|
||||||
EventCancelable::NotCancelable);
|
GlobalRef::Window(win.r()));
|
||||||
event.fire(target);
|
target.fire_simple_event_params("change",
|
||||||
|
EventBubbles::Bubbles,
|
||||||
let event = Event::new(GlobalRef::Window(win.r()),
|
EventCancelable::NotCancelable,
|
||||||
atom!("change"),
|
GlobalRef::Window(win.r()));
|
||||||
EventBubbles::Bubbles,
|
|
||||||
EventCancelable::NotCancelable);
|
|
||||||
event.fire(target);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => ()
|
_ => ()
|
||||||
|
|
|
@ -498,10 +498,7 @@ impl Runnable for ConnectionEstablishedTask {
|
||||||
// Step 5: Cookies.
|
// Step 5: Cookies.
|
||||||
|
|
||||||
// Step 6.
|
// Step 6.
|
||||||
let event = Event::new(global.r(), atom!("open"),
|
ws.upcast().fire_simple_event("open", global.r());
|
||||||
EventBubbles::DoesNotBubble,
|
|
||||||
EventCancelable::NotCancelable);
|
|
||||||
event.fire(ws.upcast());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -539,11 +536,10 @@ impl Runnable for CloseTask {
|
||||||
ws.full.set(false);
|
ws.full.set(false);
|
||||||
//A Bad close
|
//A Bad close
|
||||||
ws.clean_close.set(false);
|
ws.clean_close.set(false);
|
||||||
let event = Event::new(global.r(),
|
ws.upcast().fire_simple_event_params("error",
|
||||||
atom!("error"),
|
EventBubbles::DoesNotBubble,
|
||||||
EventBubbles::DoesNotBubble,
|
EventCancelable::Cancelable,
|
||||||
EventCancelable::Cancelable);
|
global.r());
|
||||||
event.fire(ws.upcast());
|
|
||||||
}
|
}
|
||||||
let reason = ws.reason.borrow().clone();
|
let reason = ws.reason.borrow().clone();
|
||||||
/*In addition, we also have to fire a close even if error event fired
|
/*In addition, we also have to fire a close even if error event fired
|
||||||
|
|
|
@ -126,11 +126,7 @@ impl Worker {
|
||||||
pub fn dispatch_simple_error(address: TrustedWorkerAddress) {
|
pub fn dispatch_simple_error(address: TrustedWorkerAddress) {
|
||||||
let worker = address.root();
|
let worker = address.root();
|
||||||
let global = worker.r().global.root();
|
let global = worker.r().global.root();
|
||||||
let event = Event::new(global.r(),
|
worker.upcast().fire_simple_event("error", global.r());
|
||||||
atom!("error"),
|
|
||||||
EventBubbles::DoesNotBubble,
|
|
||||||
EventCancelable::NotCancelable);
|
|
||||||
event.fire(worker.upcast());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_error_message(address: TrustedWorkerAddress, message: DOMString,
|
pub fn handle_error_message(address: TrustedWorkerAddress, message: DOMString,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue