Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of PRs in the queue #5519

Closed
wants to merge 6 commits into from
Closed
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -581,6 +581,14 @@ impl<'le> TElement<'le> for LayoutElement<'le> {
}
}

#[inline]
fn get_focus_state(self) -> bool {
unsafe {
let node: &Node = NodeCast::from_actual(self.element);
node.get_focus_state_for_layout()
}
}

#[inline]
fn get_id(self) -> Option<Atom> {
unsafe {
@@ -7,27 +7,20 @@ use syntax::codemap::Span;
use syntax::ptr::P;
use syntax::ast::{Item, MetaItem, Expr};
use syntax::ast;
use syntax::attr;
use syntax::ext::build::AstBuilder;
use syntax::ext::deriving::generic::{combine_substructure, EnumMatching, FieldInfo, MethodDef, Struct, Substructure, TraitDef, ty};
use syntax::parse::token::InternedString;

pub fn expand_dom_struct(_: &mut ExtCtxt, _: Span, _: &MetaItem, item: P<Item>) -> P<Item> {
pub fn expand_dom_struct(cx: &mut ExtCtxt, _: Span, _: &MetaItem, item: P<Item>) -> P<Item> {
let mut item2 = (*item).clone();
{
let mut add_attr = |s| {
item2.attrs.push(attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_word_item(InternedString::new(s))));
};
add_attr("must_root");
add_attr("privatize");
add_attr("jstraceable");
item2.attrs.push(quote_attr!(cx, #[must_root]));
item2.attrs.push(quote_attr!(cx, #[privatize]));
item2.attrs.push(quote_attr!(cx, #[jstraceable]));

// The following attributes are only for internal usage
add_attr("_generate_reflector");
// #[dom_struct] gets consumed, so this lets us keep around a residue
// Do NOT register a modifier/decorator on this attribute
add_attr("_dom_struct_marker");
}
// The following attributes are only for internal usage
item2.attrs.push(quote_attr!(cx, #[_generate_reflector]));
// #[dom_struct] gets consumed, so this lets us keep around a residue
// Do NOT register a modifier/decorator on this attribute
item2.attrs.push(quote_attr!(cx, #[_dom_struct_marker]));
P(item2)
}

@@ -48,9 +41,7 @@ pub fn expand_jstraceable(cx: &mut ExtCtxt, span: Span, mitem: &MetaItem, item:
explicit_self: ty::borrowed_explicit_self(),
args: vec!(ty::Ptr(box ty::Literal(ty::Path::new(vec!("js","jsapi","JSTracer"))), ty::Raw(ast::MutMutable))),
ret_ty: ty::nil_ty(),
attributes: vec!(attr::mk_attr_outer(attr::mk_attr_id(),
attr::mk_name_value_item_str(InternedString::new("inline"),
InternedString::new("always")))),
attributes: vec![quote_attr!(cx, #[inline(always)])],
combine_substructure: combine_substructure(box jstraceable_substructure)
}
],
@@ -6,8 +6,9 @@ use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::AttrBinding::{self, AttrMethods};
use dom::bindings::codegen::InheritTypes::NodeCast;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, JSRef, Temporary};
use dom::bindings::js::{OptionalRootedRootable, RootedReference};
use dom::bindings::js::{JSRef, MutNullableJS, Temporary};
use dom::bindings::js::{OptionalRootable, OptionalRootedRootable};
use dom::bindings::js::RootedReference;
use dom::bindings::utils::{Reflector, reflect_dom_object};
use dom::element::{Element, AttributeHandlers};
use dom::node::Node;
@@ -94,7 +95,7 @@ pub struct Attr {
prefix: Option<DOMString>,

/// the element that owns this attribute.
owner: Option<JS<Element>>,
owner: MutNullableJS<Element>,
}

impl Attr {
@@ -107,7 +108,7 @@ impl Attr {
name: name,
namespace: namespace,
prefix: prefix,
owner: owner.map(JS::from_rooted),
owner: MutNullableJS::new(owner),
}
}

@@ -149,7 +150,7 @@ impl<'a> AttrMethods for JSRef<'a, Attr> {

// https://dom.spec.whatwg.org/#dom-attr-value
fn SetValue(self, value: DOMString) {
match self.owner {
match self.owner() {
None => *self.value.borrow_mut() = AttrValue::String(value),
Some(o) => {
let owner = o.root();
@@ -200,7 +201,7 @@ impl<'a> AttrMethods for JSRef<'a, Attr> {

// https://dom.spec.whatwg.org/#dom-attr-ownerelement
fn GetOwnerElement(self) -> Option<Temporary<Element>> {
self.owner.map(|o| Temporary::new(o))
self.owner()
}

// https://dom.spec.whatwg.org/#dom-attr-specified
@@ -213,12 +214,14 @@ pub trait AttrHelpers<'a> {
fn set_value(self, set_type: AttrSettingType, value: AttrValue, owner: JSRef<Element>);
fn value(self) -> Ref<'a, AttrValue>;
fn local_name(self) -> &'a Atom;
fn set_owner(self, owner: Option<JSRef<Element>>);
fn owner(self) -> Option<Temporary<Element>>;
fn summarize(self) -> AttrInfo;
}

impl<'a> AttrHelpers<'a> for JSRef<'a, Attr> {
fn set_value(self, set_type: AttrSettingType, value: AttrValue, owner: JSRef<Element>) {
assert!(Some(owner) == self.owner.root().r());
assert!(Some(owner) == self.owner().root().r());

let node: JSRef<Node> = NodeCast::from_ref(owner);
let namespace_is_null = self.namespace == ns!("");
@@ -244,6 +247,28 @@ impl<'a> AttrHelpers<'a> for JSRef<'a, Attr> {
&self.extended_deref().local_name
}

/// Sets the owner element. Should be called after the attribute is added
/// or removed from its older parent.
fn set_owner(self, owner: Option<JSRef<Element>>) {
let ns = self.namespace.clone();
match (self.owner().root().r(), owner) {
(None, Some(new)) => {
// Already in the list of attributes of new owner.
assert!(new.get_attribute(ns, &self.local_name).root().r() == Some(self))
}
(Some(old), None) => {
// Already gone from the list of attributes of old owner.
assert!(old.get_attribute(ns, &self.local_name).is_none())
}
(old, new) => assert!(old == new)
}
self.owner.assign(owner)
}

fn owner(self) -> Option<Temporary<Element>> {
self.owner.get()
}

fn summarize(self) -> AttrInfo {
let Namespace(ref ns) = self.namespace;
AttrInfo {
@@ -31,26 +31,36 @@ impl Console {
}

impl<'a> ConsoleMethods for JSRef<'a, Console> {
fn Log(self, message: DOMString) {
println!("{}", message);
//TODO: Sending fake values for filename, lineNumber and columnNumber in LogMessage; adjust later
propagate_console_msg(&self, ConsoleMessage::LogMessage(message, String::from_str("test"), 1, 1));
fn Log(self, messages: Vec<DOMString>) {
for message in messages {
println!("{}", message);
//TODO: Sending fake values for filename, lineNumber and columnNumber in LogMessage; adjust later
propagate_console_msg(&self, ConsoleMessage::LogMessage(message, String::from_str("test"), 1, 1));
}
}

fn Debug(self, message: DOMString) {
println!("{}", message);
fn Debug(self, messages: Vec<DOMString>) {
for message in messages {
println!("{}", message);
}
}

fn Info(self, message: DOMString) {
println!("{}", message);
fn Info(self, messages: Vec<DOMString>) {
for message in messages {
println!("{}", message);
}
}

fn Warn(self, message: DOMString) {
println!("{}", message);
fn Warn(self, messages: Vec<DOMString>) {
for message in messages {
println!("{}", message);
}
}

fn Error(self, message: DOMString) {
println!("{}", message);
fn Error(self, messages: Vec<DOMString>) {
for message in messages {
println!("{}", message);
}
}

fn Assert(self, condition: bool, message: Option<DOMString>) {
@@ -454,7 +454,20 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> {
/// transaction, or none if no elements requested it.
fn commit_focus_transaction(self) {
//TODO: dispatch blur, focus, focusout, and focusin events

if let Some(ref elem) = self.focused.get().root() {
let node: JSRef<Node> = NodeCast::from_ref(elem.r());
node.set_focus_state(false);
}

self.focused.assign(self.possibly_focused.get());

if let Some(ref elem) = self.focused.get().root() {
let node: JSRef<Node> = NodeCast::from_ref(elem.r());
node.set_focus_state(true);
}
// TODO: Update the focus state for all elements in the focus chain.
// https://html.spec.whatwg.org/multipage/interaction.html#focus-chain
}

/// Handles any updates when the document's title has changed.
@@ -757,12 +757,13 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
});

if let Some(idx) = idx {
let attr = (*self.attrs.borrow())[idx].root();
if namespace == ns!("") {
let attr = (*self.attrs.borrow())[idx].root();
vtable_for(&NodeCast::from_ref(self)).before_remove_attr(attr.r());
}

self.attrs.borrow_mut().remove(idx);
attr.r().set_owner(None);

let node: JSRef<Node> = NodeCast::from_ref(self);
if node.is_in_doc() {
@@ -1461,6 +1462,13 @@ impl<'a> style::node::TElement<'a> for JSRef<'a, Element> {
let node: JSRef<Node> = NodeCast::from_ref(self);
node.get_hover_state()
}
fn get_focus_state(self) -> bool {
// TODO: Also check whether the top-level browsing context has the system focus,
// and whether this element is a browsing context container.
// https://html.spec.whatwg.org/multipage/scripting.html#selector-focus
let node: JSRef<Node> = NodeCast::from_ref(self);
node.get_focus_state()
}
fn get_id(self) -> Option<Atom> {
self.get_attribute(ns!(""), &atom!("id")).map(|attr| {
let attr = attr.root();
@@ -10,21 +10,21 @@ use dom::bindings::codegen::Bindings::HTMLElementBinding::HTMLElementMethods;
use dom::bindings::codegen::Bindings::HTMLInputElementBinding::HTMLInputElementMethods;
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLFrameSetElementDerived};
use dom::bindings::codegen::InheritTypes::{EventTargetCast, HTMLInputElementCast};
use dom::bindings::codegen::InheritTypes::{EventTargetCast, HTMLInputElementCast, NodeCast};
use dom::bindings::codegen::InheritTypes::{HTMLElementDerived, HTMLBodyElementDerived};
use dom::bindings::js::{JSRef, Temporary, MutNullableJS};
use dom::bindings::error::ErrorResult;
use dom::bindings::error::Error::Syntax;
use dom::bindings::utils::Reflectable;
use dom::cssstyledeclaration::{CSSStyleDeclaration, CSSModificationAccess};
use dom::document::Document;
use dom::document::{Document, DocumentHelpers};
use dom::domstringmap::DOMStringMap;
use dom::element::{Element, ElementTypeId, ActivationElementHelpers, AttributeHandlers};
use dom::eventtarget::{EventTarget, EventTargetHelpers, EventTargetTypeId};
use dom::htmlinputelement::HTMLInputElement;
use dom::htmlmediaelement::HTMLMediaElementTypeId;
use dom::htmltablecellelement::HTMLTableCellElementTypeId;
use dom::node::{Node, NodeTypeId, window_from_node};
use dom::node::{Node, NodeHelpers, NodeTypeId, document_from_node, window_from_node};
use dom::virtualmethods::VirtualMethods;
use dom::window::WindowHelpers;

@@ -135,6 +135,32 @@ impl<'a> HTMLElementMethods for JSRef<'a, HTMLElement> {
// https://www.w3.org/Bugs/Public/show_bug.cgi?id=27430 ?
element.as_maybe_activatable().map(|a| a.synthetic_click_activation(false, false, false, false));
}

// https://html.spec.whatwg.org/multipage/interaction.html#dom-focus
fn Focus(self) {
// TODO: Mark the element as locked for focus and run the focusing steps.
// https://html.spec.whatwg.org/multipage/interaction.html#focusing-steps
let element: JSRef<Element> = ElementCast::from_ref(self);
let document = document_from_node(self).root();
let document = document.r();
document.begin_focus_transaction();
document.request_focus(element);
document.commit_focus_transaction();
}

// https://html.spec.whatwg.org/multipage/interaction.html#dom-blur
fn Blur(self) {
// TODO: Run the unfocusing steps.
let node: JSRef<Node> = NodeCast::from_ref(self);
if !node.get_focus_state() {
return;
}
// https://html.spec.whatwg.org/multipage/interaction.html#unfocusing-steps
let document = document_from_node(self).root();
document.r().begin_focus_transaction();
// If `request_focus` is not called, focus will be set to None.
document.r().commit_focus_transaction();
}
}

// https://html.spec.whatwg.org/#attr-data-*
@@ -152,6 +152,8 @@ bitflags! {
#[doc = "Specifies whether or not there is an authentic click in progress on \
this element."]
const CLICK_IN_PROGRESS = 0x100,
#[doc = "Specifies whether this node has the focus."]
const IN_FOCUS_STATE = 0x200,
}
}

@@ -440,6 +442,9 @@ pub trait NodeHelpers<'a> {
fn get_hover_state(self) -> bool;
fn set_hover_state(self, state: bool);

fn get_focus_state(self) -> bool;
fn set_focus_state(self, state: bool);

fn get_disabled_state(self) -> bool;
fn set_disabled_state(self, state: bool);

@@ -618,6 +623,14 @@ impl<'a> NodeHelpers<'a> for JSRef<'a, Node> {
self.set_flag(IN_HOVER_STATE, state)
}

fn get_focus_state(self) -> bool {
self.get_flag(IN_FOCUS_STATE)
}

fn set_focus_state(self, state: bool) {
self.set_flag(IN_FOCUS_STATE, state)
}

fn get_disabled_state(self) -> bool {
self.get_flag(IN_DISABLED_STATE)
}
@@ -1036,6 +1049,8 @@ pub trait RawLayoutNodeHelpers {
#[allow(unsafe_code)]
unsafe fn get_hover_state_for_layout(&self) -> bool;
#[allow(unsafe_code)]
unsafe fn get_focus_state_for_layout(&self) -> bool;
#[allow(unsafe_code)]
unsafe fn get_disabled_state_for_layout(&self) -> bool;
#[allow(unsafe_code)]
unsafe fn get_enabled_state_for_layout(&self) -> bool;
@@ -1050,6 +1065,11 @@ impl RawLayoutNodeHelpers for Node {
}
#[inline]
#[allow(unsafe_code)]
unsafe fn get_focus_state_for_layout(&self) -> bool {
self.flags.get().contains(IN_FOCUS_STATE)
}
#[inline]
#[allow(unsafe_code)]
unsafe fn get_disabled_state_for_layout(&self) -> bool {
self.flags.get().contains(IN_DISABLED_STATE)
}
@@ -12,10 +12,10 @@

interface Console {
// These should be DOMString message, DOMString message2, ...
void log(DOMString message);
void debug(DOMString message);
void info(DOMString message);
void warn(DOMString message);
void error(DOMString message);
void log(DOMString... messages);
void debug(DOMString... messages);
void info(DOMString... messages);
void warn(DOMString... messages);
void error(DOMString... messages);
void assert(boolean condition, optional DOMString message);
};
@@ -25,8 +25,8 @@ interface HTMLElement : Element {
attribute boolean hidden;
void click();
// attribute long tabIndex;
//void focus();
//void blur();
void focus();
void blur();
// attribute DOMString accessKey;
//readonly attribute DOMString accessKeyLabel;
// attribute boolean draggable;
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.