1 use webcore::value::Reference;
2 use webcore::try_from::TryInto;
3 use webapi::event_target::{IEventTarget, EventTarget};
4 use webapi::node::{INode, Node};
5 use webapi::element::{IElement, Element};
6 use webapi::string_map::StringMap;
7 
8 /// Represents a rectangle.
9 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/DOMRect)
10 // https://drafts.fxtf.org/geometry-1/#domrect
11 #[derive(Clone, Debug, ReferenceType)]
12 #[reference(instance_of = "DOMRect")]
13 pub struct Rect (Reference);
14 
15 impl Rect {
16 
17     /// Represents the x coordinate of the DOMRect's origin
18     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/DOMRectReadOnly/x)
19     // https://drafts.fxtf.org/geometry-1/#dom-domrect-x
get_x( &self ) -> f6420     pub fn get_x( &self ) -> f64 {
21         js! (
22             return @{&self.0}.x;
23         ).try_into().unwrap()
24     }
25 
26     /// Represents the y coordinate of the DOMRect's origin.
27     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/DOMRectReadOnly/y)
28     // https://drafts.fxtf.org/geometry-1/#dom-domrect-y
get_y( &self ) -> f6429     pub fn get_y( &self ) -> f64 {
30         js! (
31             return @{&self.0}.y;
32         ).try_into().unwrap()
33     }
34 
35     /// Represents the width of the DOMRect.
36     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/DOMRectReadOnly/width)
37     // https://drafts.fxtf.org/geometry-1/#dom-domrect-width
get_width( &self ) -> f6438     pub fn get_width( &self ) -> f64 {
39         js! (
40             return @{&self.0}.width;
41         ).try_into().unwrap()
42     }
43 
44     /// Represents the height of the DOMRect.
45     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/DOMRectReadOnly/height)
46     // https://drafts.fxtf.org/geometry-1/#dom-domrect-height
get_height( &self ) -> f6447     pub fn get_height( &self ) -> f64 {
48         js! (
49             return @{&self.0}.height;
50         ).try_into().unwrap()
51     }
52 
53     /// Returns the top coordinate value of the DOMRect. (Has the same value as y, or y + height if height is negative.)
54     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/DOMRectReadOnly/top)
55     // https://drafts.fxtf.org/geometry-1/#dom-domrectreadonly-top
get_top( &self ) -> f6456     pub fn get_top( &self ) -> f64 {
57         js! (
58             return @{&self.0}.top;
59         ).try_into().unwrap()
60     }
61 
62     /// Returns the right coordinate value of the DOMRect. (Has the same value as x + width, or x if width is negative.)
63     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/DOMRectReadOnly/right)
64     // https://drafts.fxtf.org/geometry-1/#dom-domrectreadonly-right
get_right( &self ) -> f6465     pub fn get_right( &self ) -> f64 {
66         js! (
67             return @{&self.0}.right;
68         ).try_into().unwrap()
69     }
70 
71     /// Returns the bottom coordinate value of the DOMRect. (Has the same value as y + height, or y if height is negative.)
72     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/DOMRectReadOnly/bottom)
73     // https://drafts.fxtf.org/geometry-1/#dom-domrectreadonly-bottom
get_bottom( &self ) -> f6474     pub fn get_bottom( &self ) -> f64 {
75         js! (
76             return @{&self.0}.bottom;
77         ).try_into().unwrap()
78     }
79 
80     /// Returns the left coordinate value of the DOMRect. (Has the same value as x, or x + width if width is negative.)
81     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/DOMRectReadOnly/left)
82     // https://drafts.fxtf.org/geometry-1/#dom-domrectreadonly-left
get_left( &self ) -> f6483     pub fn get_left( &self ) -> f64 {
84         js! (
85             return @{&self.0}.left;
86         ).try_into().unwrap()
87     }
88 }
89 
90 /// The `IHtmlElement` interface represents any HTML element.
91 ///
92 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement)
93 // https://html.spec.whatwg.org/#htmlelement
94 pub trait IHtmlElement: IElement {
95     /// Sets focus on the specified element, if it can be focused.
96     ///
97     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus)
98     // https://html.spec.whatwg.org/#elements-in-the-dom:dom-focus
focus( &self )99     fn focus( &self ) {
100         js! { @(no_return)
101             @{self.as_ref()}.focus();
102         }
103     }
104 
105     /// Removes keyboard focus from the current element.
106     ///
107     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/blur)
108     // https://html.spec.whatwg.org/#elements-in-the-dom:dom-blur
blur( &self )109     fn blur( &self ) {
110         js! { @(no_return)
111             @{self.as_ref()}.blur();
112         }
113     }
114 
115     /// Allows access, both in reading and writing, to all of the custom data attributes (data-*)
116     /// set on the element, either in HTML or in the DOM.
117     ///
118     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset)
119     // https://html.spec.whatwg.org/#elements-in-the-dom:dom-dataset
dataset( &self ) -> StringMap120     fn dataset( &self ) -> StringMap {
121         unsafe {
122             js!(
123                 return @{self.as_ref()}.dataset;
124             ).into_reference_unchecked().unwrap()
125         }
126     }
127 
128     /// Returns the size of an element and its position relative to the viewport.
129     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect)
130     // https://drafts.csswg.org/cssom-view/#ref-for-dom-element-getboundingclientrect
get_bounding_client_rect( &self ) -> Rect131     fn get_bounding_client_rect( &self ) -> Rect {
132         js! (
133             return @{self.as_ref()}.getBoundingClientRect();
134         ).try_into().unwrap()
135     }
136 
137     /// Returns the layout width of an element. Typically, an element's offsetWidth is a
138     /// measurement which includes the element borders, the element horizontal padding, the
139     /// element vertical scrollbar (if present, if rendered) and the element CSS width.
140     // https://drafts.csswg.org/cssom-view/#ref-for-dom-htmlelement-offsetwidth
offset_width( &self ) -> i32141     fn offset_width( &self ) -> i32 {
142         js!(
143             return @{self.as_ref()}.offsetWidth;
144         ).try_into().unwrap()
145     }
146 
147     /// Returns the height of the element including vertical padding and borders, as an
148     /// integer.
149     // https://drafts.csswg.org/cssom-view/#ref-for-dom-htmlelement-offsetheight
offset_height( &self ) -> i32150     fn offset_height( &self ) -> i32 {
151         js!(
152             return @{self.as_ref()}.offsetHeight;
153         ).try_into().unwrap()
154     }
155 
156     /// A property which represents the "rendered" text content of a node and its descendants.
157     /// It approximates the text the user would get if they highlighted the contents of the element
158     /// with the cursor and then copied to the clipboard.
159     ///
160     /// This feature was originally introduced by Internet Explorer, and was formally specified in the HTML
161     /// standard in 2016 after being adopted by all major browser vendors.
162     ///
163     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/Node/innerText)
164     // https://html.spec.whatwg.org/#elements-in-the-dom:dom-innertext
inner_text( &self ) -> String165     fn inner_text( &self ) -> String {
166         js!(
167             return @{self.as_ref()}.innerText;
168         ).try_into().unwrap()
169     }
170 }
171 
172 /// A reference to a JavaScript object which implements the [IHtmlElement](trait.IHtmlElement.html)
173 /// interface.
174 ///
175 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement)
176 #[derive(Clone, Debug, PartialEq, Eq, ReferenceType)]
177 #[reference(instance_of = "HTMLElement")]
178 #[reference(subclass_of(EventTarget, Node, Element))]
179 pub struct HtmlElement( Reference );
180 
181 impl IEventTarget for HtmlElement {}
182 impl INode for HtmlElement {}
183 impl IElement for HtmlElement {}
184 impl IHtmlElement for HtmlElement {}
185 
186 #[cfg(all(test, feature = "web_test"))]
187 mod tests {
188     use super::*;
189 
div() -> Element190     fn div() -> Element {
191         js!(
192             return document.createElement("div");
193         ).try_into().unwrap()
194     }
195 
text(text: &str) -> Node196     fn text(text: &str) -> Node {
197         js!(
198             return new Text(@{text});
199         ).try_into().unwrap()
200     }
201 
202     #[test]
test_inner_text()203     fn test_inner_text() {
204         let element: HtmlElement = div().try_into().unwrap();
205         assert_eq!(element.inner_text(), "");
206         element.append_child(&text("foo "));
207         assert_eq!(element.inner_text(), "foo ");
208         element.append_child(&text("foo"));
209         assert_eq!(element.inner_text(), "foo foo");
210     }
211 }
212