sciter/
dom.rs

1/*! DOM access methods via the [`dom::Element`](struct.Element.html).
2
3
4## Introduction.
5
6Let’s assume you have already integrated Sciter in your application and so you have a Sciter window with the loaded content.
7
8From Sciter's point of view the loaded document is a tree of DOM elements (elements of Document Object Model).
9Sciter builds this tree while loading/parsing of input HTML.
10As a rule, each tag in the source HTML is matching with a DOM element (there are exceptions, see below).
11
12You can change the text, attributes, state flags of DOM elements;
13add new or remove existing DOM elements.
14You can also attach your own DOM event handlers to DOM elements in order to receive events and notifications.
15
16Therefore your UI in Sciter is a collection of uniform DOM elements
17that can be styled by CSS and manipulated by native or script code.
18
19
20## Basic operations
21
22To access the DOM tree we need to get a reference of its root element
23(the root element is the element representing the `<html>` tag in HTML source).
24
25```rust,no_run
26# use sciter::dom::Element;
27# let hwnd = ::std::ptr::null_mut();
28let root = Element::from_window(hwnd).unwrap();
29assert_eq!(root.get_tag(), "html");
30```
31
32*TBD:* Other ways to access DOM tree.
33
34By having a root element reference we are able to access any other element in the tree
35using various access and search functions like `SciterGetNthChild`, `SciterSelectElements`, etc.
36All of them are wrapped into methods of [`dom::Element`](struct.Element.html).
37
38Here is how you would get a reference to the first `<div>` element with class "sidebar" using CSS selectors:
39
40```rust,no_run
41# let root = sciter::dom::Element::from(::std::ptr::null_mut());
42let sidebar = root.find_first("div.sidebar").unwrap();
43```
44
45The same in script:
46
47```tiscript
48var sidebar = self.select("div.sidebar"); // or
49var sidebar = self.$(div.sidebar); // using the stringizer variant of select()
50```
51
52*TBD:* Other select methods.
53
54## DOM element operations
55
56You can change the **text** or **html** of a DOM element:
57
58```rust,no_run
59# let root = sciter::dom::Element::from(::std::ptr::null_mut());
60if let Some(mut el) = root.find_first("#cancel").unwrap() {
61  el.set_text("Abort!");
62  el.set_html(br##"<img src="http://lorempixel.com/32/32/cats/" alt="some cat"/>"##, None);
63}
64```
65
66The same but in script:
67
68```tiscript
69var el = ...;
70el.text = "Hello world"; // text
71el.html = "Hello <b>wrold</b>!"; // inner html
72```
73
74You can also get or set DOM **attributes** of any DOM element:
75
76```rust,no_run
77# let mut el = sciter::dom::Element::from(::std::ptr::null_mut());
78let val = el.get_attribute("class").unwrap();
79el.set_attribute("class", "new-class");
80```
81
82To **remove** an existing DOM element (to detach it from the DOM) you will do this:
83
84```rust,no_run
85# let mut el = sciter::dom::Element::from(::std::ptr::null_mut());
86el.detach();
87```
88
89and when the code leaves the scope where the `el` variable is defined, the DOM element will be destroyed.
90
91Creation and population of DOM elements looks like this:
92
93```rust,no_run
94# use sciter::dom::Element;
95# let mut el = sciter::dom::Element::from(::std::ptr::null_mut());
96let p = Element::with_text("p", "Hello").unwrap(); // create <p> element
97el.append(&p); // append it to the existing element, or use insert() ...
98```
99
100And in script:
101
102```tiscript
103var p = new Element("p", "Hello");
104el.append(p);
105```
106
107To change runtime state flags of a DOM element we do something like this:
108
109```rust,ignore
110# let mut el = sciter::dom::Element::from(::std::ptr::null_mut());
111el.set_state(ELEMENT_STATE_BITS::STATE_VISITED);
112```
113
114And in script:
115
116```tiscript
117el.state.visited = true;
118```
119
120(after such call the element will match the `:visited` CSS selector)
121
122
123## Getting and setting values of DOM elements.
124
125By default the value of a DOM element is its text but some DOM elements may have
126so called behaviors attached to them (see below).
127`<input>` elements, for example, are plain DOM elements
128but each input type has its own behavior assigned to the element.
129The behavior, among other things, is responsible for providing and setting the value of the element.
130
131For example, the value of an `<input type=checkbox>` is boolean – _true_ or _false_,
132and the value of a `<form>` element is a collection (name/value map) of all named inputs on the form.
133
134In native code values are represented by [`sciter::Value`](../value/index.html) objects.
135[`sciter::Value`](../value/index.html) is a structure that can hold different types of values:
136numbers, strings, arrays, objects, etc
137(see [documentation](https://sciter.com/docs/content/script/language/Types.htm)).
138
139Here is how to set a numeric value of a DOM element in native code:
140
141```rust,no_run
142# use sciter::Value;
143# let root = sciter::dom::Element::from(::std::ptr::null_mut());
144if let Some(mut num) = root.find_first("input[type=number]").unwrap() {
145  num.set_value( Value::from(12) );  // sciter::Value with T_INT type (i32 in Rust)
146  num.set_value(12);  // equivalent but with implicit conversion
147}
148```
149
150In script the same will look like:
151
152```tiscript
153if (var num = self.select("input[type=number]")) {
154  num.value = 12;
155}
156```
157
158.
159*/
160
161use ::{_API};
162use capi::sctypes::*;
163use value::Value;
164
165use capi::screquest::{REQUEST_PARAM, REQUEST_TYPE};
166use capi::scdef::RESOURCE_TYPE;
167use capi::scbehavior::{CLICK_REASON, BEHAVIOR_EVENTS, BEHAVIOR_EVENT_PARAMS};
168use utf::{store_astr, store_wstr, store_bstr};
169
170pub use capi::scdom::{SCDOM_RESULT, HELEMENT, SET_ELEMENT_HTML, ELEMENT_AREAS, ELEMENT_STATE_BITS};
171pub use dom::event::{EventHandler, EventReason};
172
173
174/// A specialized `Result` type for DOM operations.
175pub type Result<T> = ::std::result::Result<T, SCDOM_RESULT>;
176
177
178/// Initialize HELEMENT by nullptr.
179macro_rules! HELEMENT {
180	() => { ::std::ptr::null_mut() }
181}
182
183
184macro_rules! ok_or {
185	($rv:expr, $ok:ident) => {
186		if $ok == SCDOM_RESULT::OK {
187			Ok($rv)
188		} else {
189			Err($ok)
190		}
191	};
192
193	// for DOM access not_handled is ok
194	// for calling function operation_failed is also ok
195	($rv:expr, $ok:ident, $skip_not_handled:expr) => {
196		if $ok == SCDOM_RESULT::OK || ($ok == $skip_not_handled) {
197			Ok($rv)
198		} else {
199			Err($ok)
200		}
201	};
202}
203
204
205trait ElementVisitor {
206	fn on_element(&mut self, el: Element) -> bool;
207	fn result(&self) -> Vec<Element>;
208}
209
210#[derive(Default)]
211struct FindFirstElement {
212	all: Vec<Element>,
213}
214
215impl ElementVisitor for FindFirstElement {
216	fn on_element(&mut self, el: Element) -> bool {
217		self.all.push(el);
218		return true;	// stop enumeration
219	}
220	fn result(&self) -> Vec<Element> {
221		self.all.clone()
222	}
223}
224
225#[derive(Default)]
226struct FindAllElements {
227	all: Vec<Element>,
228}
229
230impl ElementVisitor for FindAllElements {
231	fn on_element(&mut self, el: Element) -> bool {
232		self.all.push(el);
233		return false;	// continue enumeration
234	}
235	fn result(&self) -> Vec<Element> {
236		self.all.clone()
237	}
238}
239
240
241/// DOM element wrapper. See the module-level documentation also.
242#[derive(PartialEq)]
243pub struct Element {
244	he: HELEMENT,
245}
246
247/// `sciter::Element` can be transferred across thread boundaries.
248unsafe impl Send for Element {}
249
250/// It is safe to share `sciter::Element` between threads - underlaying API is thread-safe.
251unsafe impl Sync for Element {}
252
253impl From<HELEMENT> for Element {
254	/// Construct an Element object from an `HELEMENT` handle.
255	fn from(he: HELEMENT) -> Self {
256		Element { he: Element::use_or(he) }
257	}
258}
259
260const DOM_UNWRAP_API_VERSION: u32 = 0x0000_0007;
261
262/// Store the DOM element as a `Value`.
263///
264/// Since 4.4.3.26, perhaps.
265impl std::convert::TryFrom<Element> for Value {
266	type Error = SCDOM_RESULT;
267	fn try_from(e: Element) -> Result<Value> {
268		let mut v = Value::new();
269		let ok = if crate::api_version() >= DOM_UNWRAP_API_VERSION {
270			(_API.SciterElementWrap)(v.as_mut_ptr(), e.as_ptr())
271		} else {
272			(_API.SciterGetExpando)(e.as_ptr(), v.as_ptr(), true as BOOL)
273		};
274		ok_or!(v, ok)
275	}
276}
277
278/// Get an `Element` object contained in the `Value`.
279impl crate::value::FromValue for Element {
280	fn from_value(v: &Value) -> Option<Element> {
281		if crate::api_version() >= DOM_UNWRAP_API_VERSION {
282			let mut h = std::ptr::null_mut();
283			let ok = (_API.SciterElementUnwrap)(v.as_cptr(), &mut h);
284			if ok == SCDOM_RESULT::OK {
285				Some(Element::from(h))
286			} else {
287				None
288			}
289		} else {
290			let mut pv: LPCBYTE = std::ptr::null();
291			let mut cb: UINT = 0;
292			let ok = (_API.ValueBinaryData)(v.as_cptr(), &mut pv, &mut cb);
293			if ok == crate::value::VALUE_RESULT::OK {
294				Some(Element::from(pv as HELEMENT))
295			} else {
296				None
297			}
298		}
299	}
300}
301
302impl Element {
303
304	//\name Creation
305
306	/// Create a new element, it is disconnected initially from the DOM.
307	pub fn create(tag: &str) -> Result<Element> {
308		let mut e = Element { he: HELEMENT!() };
309		let tag = s2u!(tag);
310		let text = 0 as LPCWSTR;
311		let ok = (_API.SciterCreateElement)(tag.as_ptr(), text, &mut e.he);
312		ok_or!(e, ok)
313	}
314
315	/// Create new element as child of `parent`.
316	pub fn with_parent(tag: &str, parent: &mut Element) -> Result<Element> {
317		let mut e = Element { he: HELEMENT!() };
318		let tag = s2u!(tag);
319		let text = 0 as LPCWSTR;
320		(_API.SciterCreateElement)(tag.as_ptr(), text, &mut e.he);
321		let ok = parent.append(&e);
322		ok.map(|_| e)
323	}
324
325	/// Create new element as child of `parent`. Deprecated.
326	#[deprecated(since="0.5.0", note="please use `Element::with_parent()` instead.")]
327	pub fn create_at(tag: &str, parent: &mut Element) -> Result<Element> {
328		Element::with_parent(tag, parent)
329	}
330
331	/// Create new element with specified `text`, it is disconnected initially from the DOM.
332	pub fn with_text(tag: &str, text: &str) -> Result<Element> {
333		let mut e = Element { he: HELEMENT!() };
334		let tag = s2u!(tag);
335		let text = s2w!(text);
336		let ok = (_API.SciterCreateElement)(tag.as_ptr(), text.as_ptr(), &mut e.he);
337		ok_or!(e, ok)
338	}
339
340	/// Create new element with specified `type`, which is useful for controls and widgets (initially disconnected).
341	pub fn with_type(tag: &str, el_type: &str) -> Result<Element> {
342		let mut e = Element { he: HELEMENT!() };
343		let tag = s2u!(tag);
344		let text = 0 as LPCWSTR;
345		let ok = (_API.SciterCreateElement)(tag.as_ptr(), text, &mut e.he);
346		if ok == SCDOM_RESULT::OK {
347			let r = e.set_attribute("type", el_type);
348			r.map(|_| e)
349		} else {
350			Err(ok)
351		}
352	}
353
354	/// Check the given element for `NULL` and returns [`SCDOM_RESULT::OK_NOT_HANDLED`] in that case.
355	///
356	/// Some functions, like `SciterGetRootElement` or `SciterGetHighlightedElement`
357	/// return `OK` if no element found, but `HELEMENT` is `NULL`.
358	///
359	/// We might want to switch to an `Result<Option<Element>> for `Element::from_*` functions,
360	/// but for now let's return an error for such cases.
361	///
362	/// https://github.com/sciter-sdk/rust-sciter/issues/27
363	fn forbid_null(e: Element) -> Result<Element> {
364		if e.he.is_null() {
365			Err(SCDOM_RESULT::OK_NOT_HANDLED)
366		} else {
367			Ok(e)
368		}
369	}
370
371	/// Get the root DOM element of the Sciter document.
372	///
373	/// If there is no document loaded, this function will return [an error](enum.SCDOM_RESULT.html#variant.OK_NOT_HANDLED).
374	pub fn from_window(hwnd: HWINDOW) -> Result<Element> {
375		let mut p = HELEMENT!();
376		let ok = (_API.SciterGetRootElement)(hwnd, &mut p);
377		ok_or!(Element::from(p), ok).and_then(Element::forbid_null)
378	}
379
380	/// Get focus DOM element of the Sciter document.
381	///
382	/// If there is no such element, this function will return [an error](enum.SCDOM_RESULT.html#variant.OK_NOT_HANDLED).
383	pub fn from_focus(hwnd: HWINDOW) -> Result<Element> {
384		let mut p = HELEMENT!();
385		let ok = (_API.SciterGetFocusElement)(hwnd, &mut p);
386		ok_or!(Element::from(p), ok).and_then(Element::forbid_null)
387	}
388
389	/// Get highlighted element.
390	///
391	/// If there is no such element, this function will return [an error](enum.SCDOM_RESULT.html#variant.OK_NOT_HANDLED).
392	pub fn from_highlighted(hwnd: HWINDOW) -> Result<Element> {
393		let mut p = HELEMENT!();
394		let ok = (_API.SciterGetHighlightedElement)(hwnd, &mut p);
395		ok_or!(Element::from(p), ok).and_then(Element::forbid_null)
396	}
397
398	/// Find DOM element of the Sciter document by coordinates.
399	///
400	/// If there is no such element, this function will return [an error](enum.SCDOM_RESULT.html#variant.OK_NOT_HANDLED).
401	pub fn from_point(hwnd: HWINDOW, pt: POINT) -> Result<Element> {
402		let mut p = HELEMENT!();
403		let ok = (_API.SciterFindElement)(hwnd, pt, &mut p);
404		ok_or!(Element::from(p), ok).and_then(Element::forbid_null)
405	}
406
407	/// Get element handle by its UID.
408	///
409	/// If there is no such element, this function will return [an error](enum.SCDOM_RESULT.html#variant.OK_NOT_HANDLED).
410	pub fn from_uid(hwnd: HWINDOW, uid: u32) -> Result<Element> {
411		let mut p = HELEMENT!();
412		let ok = (_API.SciterGetElementByUID)(hwnd, uid, &mut p);
413		ok_or!(Element::from(p), ok).and_then(Element::forbid_null)
414	}
415
416	#[doc(hidden)]
417	fn use_or(he: HELEMENT) -> HELEMENT {
418		let ok = (_API.Sciter_UseElement)(he);
419		if ok == SCDOM_RESULT::OK {
420			he
421		} else {
422			HELEMENT!()
423		}
424	}
425
426
427	//\name Common methods
428
429	/// Access element pointer.
430	pub fn as_ptr(&self) -> HELEMENT {
431		self.he
432	}
433
434	/// Get element UID - identifier suitable for storage.
435	pub fn get_uid(&self) -> u32 {
436		let mut n = 0;
437		(_API.SciterGetElementUID)(self.he, &mut n);
438		return n;
439	}
440
441	/// Return element tag as string (e.g. 'div', 'body').
442	pub fn get_tag(&self) -> String {
443		let mut s = String::new();
444		(_API.SciterGetElementTypeCB)(self.he, store_astr, &mut s as *mut String as LPVOID);
445		return s;
446	}
447
448	/// Get inner text of the element as string.
449	pub fn get_text(&self) -> String {
450		let mut s = String::new();
451		(_API.SciterGetElementTextCB)(self.he, store_wstr, &mut s as *mut String as LPVOID);
452		return s;
453	}
454
455	/// Set inner text of the element.
456	pub fn set_text(&mut self, text: &str) -> Result<()> {
457		let (s,n) = s2wn!(text);
458		let ok = (_API.SciterSetElementText)(self.he, s.as_ptr(), n);
459		ok_or!((), ok)
460	}
461
462	/// Get html representation of the element as utf-8 bytes.
463	pub fn get_html(&self, with_outer_html: bool) -> Vec<u8> {
464		let mut s = Vec::new();
465		(_API.SciterGetElementHtmlCB)(self.he, with_outer_html as BOOL, store_bstr, &mut s as *mut Vec<u8> as LPVOID);
466		return s;
467	}
468
469	/// Set inner or outer html of the element.
470	pub fn set_html(&mut self, html: &[u8], how: Option<SET_ELEMENT_HTML>) -> Result<()> {
471		if html.is_empty() {
472			return self.clear();
473		}
474		let ok = (_API.SciterSetElementHtml)(self.he, html.as_ptr(), html.len() as UINT, how.unwrap_or(SET_ELEMENT_HTML::SIH_REPLACE_CONTENT) as UINT);
475		ok_or!((), ok)
476	}
477
478	/// Get value of the element.
479	pub fn get_value(&self) -> Value {
480		let mut rv = Value::new();
481		(_API.SciterGetValue)(self.he, rv.as_ptr());
482		return rv;
483	}
484
485	/// Set value of the element.
486	pub fn set_value<T: Into<Value>>(&mut self, val: T) -> Result<()> {
487		let ok = (_API.SciterSetValue)(self.he, val.into().as_cptr());
488		ok_or!((), ok)
489	}
490
491	/// Checks if particular UI state bits are set in the element.
492	pub fn get_state(&self) -> ELEMENT_STATE_BITS {
493		let mut rv = 0u32;
494		(_API.SciterGetElementState)(self.he, &mut rv as *mut _);
495		let state = unsafe { ::std::mem::transmute(rv) };
496		return state;
497	}
498
499	/// Set UI state of the element with optional view update.
500	pub fn set_state(&mut self, set: ELEMENT_STATE_BITS, clear: Option<ELEMENT_STATE_BITS>, update: bool) -> Result<()> {
501		let clear = clear.unwrap_or(ELEMENT_STATE_BITS::STATE_NONE);
502		let ok = (_API.SciterSetElementState)(self.he, set as UINT, clear as UINT, update as BOOL);
503		ok_or!((), ok)
504	}
505
506	/// Get `HWINDOW` of containing window.
507	pub fn get_hwnd(&self, for_root: bool) -> HWINDOW {
508		let mut hwnd: HWINDOW = ::std::ptr::null_mut();
509		(_API.SciterGetElementHwnd)(self.he, &mut hwnd as *mut HWINDOW, for_root as BOOL);
510		return hwnd;
511	}
512
513	/// Attach a native window to the element as a child.
514	pub fn attach_hwnd(&mut self, child: HWINDOW) -> Result<()> {
515		let ok = (_API.SciterAttachHwndToElement)(self.he, child);
516		ok_or!((), ok)
517	}
518
519	/// Detach a child native window (if any) from the element.
520	pub fn detach_hwnd(&mut self) -> Result<()> {
521		let ok = (_API.SciterAttachHwndToElement)(self.he, 0 as HWINDOW);
522		ok_or!((), ok)
523	}
524
525	/// Get bounding rectangle of the element. See the [`ELEMENT_AREAS`](enum.ELEMENT_AREAS.html) enum for `kind` flags.
526	pub fn get_location(&self, kind: u32) -> Result<RECT> {
527		let mut rc = RECT::default();
528		let ok = (_API.SciterGetElementLocation)(self.he, &mut rc as *mut _, kind as u32);
529		ok_or!(rc, ok)
530	}
531
532	/// Request data download for this element.
533	pub fn request_data(&self, url: &str, data_type: RESOURCE_TYPE, initiator: Option<HELEMENT>) -> Result<()> {
534		let url = s2w!(url);
535		let ok = (_API.SciterRequestElementData)(self.he, url.as_ptr(), data_type as u32, initiator.unwrap_or(HELEMENT!()));
536		ok_or!((), ok)
537	}
538
539	/// Request HTML data download for this element.
540	pub fn request_html(&self, url: &str, initiator: Option<HELEMENT>) -> Result<()> {
541		self.request_data(url, RESOURCE_TYPE::HTML, initiator)
542	}
543
544	/// Send an asynchronous HTTP GET request for the element.
545	///
546	/// The contents of this element is replaced with the HTTP response (in text or html form).
547	pub fn send_get_request(&self, url: &str) -> Result<()> {
548		let url = s2w!(url);
549		let no_params = ::std::ptr::null();
550		let ok = (_API.SciterHttpRequest)(self.he, url.as_ptr(), RESOURCE_TYPE::HTML as u32, REQUEST_TYPE::AsyncGet as u32, no_params, 0);
551		ok_or!((), ok)
552	}
553
554	/// Send an HTTP GET or POST request for the element.
555	///
556	/// GET params (if any) are appended to the url to form the request.<br/>
557	/// HTTP POST params are serialized as `Content-Type: application/x-www-form-urlencoded;charset=utf-8;`.
558	pub fn send_request(&self, url: &str, params: Option<&[(&str, &str)]>, method: Option<REQUEST_TYPE>, data_type: Option<RESOURCE_TYPE>) -> Result<()> {
559
560		let url = s2w!(url);
561		let method = method.unwrap_or(REQUEST_TYPE::AsyncGet) as u32;
562		let data_type = data_type.unwrap_or(RESOURCE_TYPE::HTML) as u32;
563
564		type WSTR = Vec<u16>;
565
566		let mut wide_params: Vec<(WSTR, WSTR)> = Vec::new();
567		let mut call_params: Vec<REQUEST_PARAM> = Vec::new();
568
569		if let Some(params) = params {
570			let count = params.len();
571
572			wide_params.reserve_exact(count);
573			call_params.reserve_exact(count);
574
575			for (k,v) in params {
576				let (kw, vw) = (s2w!(k), s2w!(v));
577				call_params.push (REQUEST_PARAM {
578					name: kw.as_ptr(),
579					value: vw.as_ptr(),
580				});
581				wide_params.push((kw, vw));
582			}
583		}
584
585		let ok = (_API.SciterHttpRequest)(self.he, url.as_ptr(), data_type, method, call_params.as_ptr(), call_params.len() as u32);
586		ok_or!((), ok)
587	}
588
589	/// Sends sinking/bubbling event to the child/parent chain of the element.
590	pub fn send_event(&self, code: BEHAVIOR_EVENTS, reason: Option<CLICK_REASON>, source: Option<HELEMENT>) -> Result<bool> {
591		let mut handled = false as BOOL;
592		let r = reason.unwrap_or(CLICK_REASON::SYNTHESIZED);
593		let s = source.unwrap_or(self.he);
594		let ok = (_API.SciterSendEvent)(self.he, code as u32, s, r as UINT_PTR, &mut handled);
595		ok_or!(handled != 0, ok)
596	}
597
598	/// Post asynchronously a sinking/bubbling event to the child/parent chain of the element.
599	pub fn post_event(&self, code: BEHAVIOR_EVENTS, reason: Option<CLICK_REASON>, source: Option<HELEMENT>) -> Result<()> {
600		let r = reason.unwrap_or(CLICK_REASON::SYNTHESIZED);
601		let s = source.unwrap_or(self.he);
602		let ok = (_API.SciterPostEvent)(self.he, code as u32, s, r as UINT_PTR);
603		ok_or!((), ok)
604	}
605
606	/// Send or posts event to the child/parent chain of the element.
607	pub fn fire_event(&self, code: BEHAVIOR_EVENTS, reason: Option<CLICK_REASON>, source: Option<HELEMENT>, post: bool, data: Option<Value>) -> Result<bool> {
608		let mut handled = false as BOOL;
609		let mut params = BEHAVIOR_EVENT_PARAMS {
610			cmd: code as UINT,
611			reason: reason.unwrap_or(CLICK_REASON::SYNTHESIZED) as UINT_PTR,
612			he: source.unwrap_or(self.he),
613			heTarget: self.he,
614			data: Default::default(),
615			name: 0 as LPCWSTR,
616		};
617		if let Some(data) = data {
618			data.pack_to(&mut params.data);
619		}
620		let ok = (_API.SciterFireEvent)(&params, post as BOOL, &mut handled);
621		ok_or!(handled != 0, ok)
622	}
623
624	/// Send or posts event with specified params to the child/parent chain of the element.
625	pub fn fire_event_params(evt: &BEHAVIOR_EVENT_PARAMS, post: bool) -> Result<bool> {
626		let mut handled = false as BOOL;
627		let ok = (_API.SciterFireEvent)(evt, post as BOOL, &mut handled);
628		ok_or!(handled != 0, ok)
629	}
630
631	/// Broadcast a custom named event to all windows.
632	pub fn broadcast_event(&self, name: &str, post: bool, data: Option<Value>) -> Result<bool> {
633		let name = s2w!(name);
634		let mut  params = BEHAVIOR_EVENT_PARAMS {
635			cmd: BEHAVIOR_EVENTS::CUSTOM as UINT,
636			heTarget: HELEMENT!(),
637			reason: 0,
638			he: self.he,
639			name: name.as_ptr(),
640			data: Default::default(),
641		};
642		if let Some(data) = data {
643			data.pack_to(&mut params.data);
644		}
645		let mut handled = false as BOOL;
646		let ok = (_API.SciterFireEvent)(&params, post as BOOL, &mut handled);
647		ok_or!(handled != 0, ok)
648	}
649
650
651	/// Evaluate the given script in context of the element.
652	pub fn eval_script(&self, script: &str) -> Result<Value> {
653		let mut rv = Value::new();
654		let (s,n) = s2wn!(script);
655		let ok = (_API.SciterEvalElementScript)(self.he, s.as_ptr(), n, rv.as_ptr());
656		return ok_or!(rv, ok, SCDOM_RESULT::OPERATION_FAILED);
657	}
658
659	/// Call scripting function defined in the namespace of the element (a.k.a. global function).
660	///
661	/// You can use the [`make_args!(args...)`](../macro.make_args.html) macro which helps you
662	/// to construct script arguments from Rust types.
663	pub fn call_function(&self, name: &str, args: &[Value]) -> Result<Value> {
664		let mut rv = Value::new();
665		let name = s2u!(name);
666		let argv = Value::pack_args(args);
667		let ok = (_API.SciterCallScriptingFunction)(self.he, name.as_ptr(), argv.as_ptr(), argv.len() as UINT, rv.as_ptr());
668		return ok_or!(rv, ok, SCDOM_RESULT::OPERATION_FAILED);
669	}
670
671	/// Call scripting method defined for the element.
672	///
673	/// You can use the [`make_args!(args...)`](../macro.make_args.html) macro which helps you
674	/// to construct script arguments from Rust types.
675	pub fn call_method(&self, name: &str, args: &[Value]) -> Result<Value> {
676		let mut rv = Value::new();
677		let name = s2u!(name);
678		let argv = Value::pack_args(args);
679		let ok = (_API.SciterCallScriptingMethod)(self.he, name.as_ptr(), argv.as_ptr(), argv.len() as UINT, rv.as_ptr());
680		return ok_or!(rv, ok, SCDOM_RESULT::OPERATION_FAILED);
681	}
682
683  /// Call behavior specific method.
684  pub fn call_behavior_method(&self, params: event::MethodParams) -> Result<()> {
685    let call = |p| {
686      (_API.SciterCallBehaviorMethod)(self.he, p)
687    };
688    use capi::scbehavior::{METHOD_PARAMS, VALUE_PARAMS, IS_EMPTY_PARAMS};
689    use capi::scbehavior::BEHAVIOR_METHOD_IDENTIFIERS::*;
690    let ok = match params {
691      event::MethodParams::Click => {
692        let mut p = METHOD_PARAMS {
693          method: DO_CLICK as u32,
694        };
695        call(&mut p as *mut _)
696      },
697      event::MethodParams::SetValue(v) => {
698        let mut p = VALUE_PARAMS {
699          method: SET_VALUE as u32,
700          value: Default::default(),
701        };
702        v.pack_to(&mut p.value);
703        call(&mut p as *mut _ as *mut METHOD_PARAMS)
704      },
705      event::MethodParams::GetValue(retv) => {
706        let mut p = VALUE_PARAMS {
707          method: SET_VALUE as u32,
708          value: Default::default(),
709        };
710        let ok = call(&mut p as *mut _ as *mut METHOD_PARAMS);
711        if ok != SCDOM_RESULT::OK {
712          return Err(ok);
713        }
714        *retv = Value::from(&p.value);
715        ok
716      },
717      event::MethodParams::IsEmpty(retv) => {
718        let mut p = IS_EMPTY_PARAMS {
719          method: IS_EMPTY as u32,
720          is_empty: Default::default(),
721        };
722        let ok = call(&mut p as *mut _ as *mut METHOD_PARAMS);
723        if ok != SCDOM_RESULT::OK {
724          return Err(ok);
725        }
726        *retv = p.is_empty != 0;
727        ok
728      },
729
730      _ => {
731        // Can't handle `MethodParams::Custom` yet.
732        SCDOM_RESULT::INVALID_PARAMETER
733      },
734    };
735    ok_or!((), ok)
736  }
737
738
739	//\name Attributes
740	/// Get number of the attributes.
741	pub fn attribute_count(&self) -> usize {
742		let mut n = 0u32;
743		(_API.SciterGetAttributeCount)(self.he, &mut n);
744		return n as usize;
745	}
746
747	/// Get attribute name by its index.
748	pub fn attribute_name(&self, index: usize) -> String {
749		let mut s = String::new();
750		(_API.SciterGetNthAttributeNameCB)(self.he, index as UINT, store_astr, &mut s as *mut String as LPVOID);
751		return s;
752	}
753
754	/// Get attribute value by its index.
755	pub fn attribute(&self, index: usize) -> String {
756		let mut s = String::new();
757		(_API.SciterGetNthAttributeValueCB)(self.he, index as UINT, store_wstr, &mut s as *mut String as LPVOID);
758		return s;
759	}
760
761	/// Get attribute value by its name.
762	pub fn get_attribute(&self, name: &str) -> Option<String> {
763		let mut s = String::new();
764		let name = s2u!(name);
765		let ok = (_API.SciterGetAttributeByNameCB)(self.he, name.as_ptr(), store_wstr, &mut s as *mut String as LPVOID);
766		match ok {
767			SCDOM_RESULT::OK => Some(s),
768			// SCDOM_RESULT::OK_NOT_HANDLED => None,
769			_ => None,
770		}
771	}
772
773	/// Add or replace attribute.
774	pub fn set_attribute(&mut self, name: &str, value: &str) -> Result<()> {
775		let name = s2u!(name);
776		let value = s2w!(value);
777		let ok = (_API.SciterSetAttributeByName)(self.he, name.as_ptr(), value.as_ptr());
778		ok_or!((), ok)
779	}
780
781	/// Remove attribute.
782	pub fn remove_attribute(&mut self, name: &str) -> Result<()> {
783		let name = s2u!(name);
784		let value = ::std::ptr::null();
785		let ok = (_API.SciterSetAttributeByName)(self.he, name.as_ptr(), value);
786		ok_or!((), ok)
787	}
788
789	/// Toggle attribute.
790	pub fn toggle_attribute(&mut self, name: &str, isset: bool, value: Option<&str>) -> Result<()> {
791		if isset {
792			self.set_attribute(name, value.unwrap())
793		} else {
794			self.remove_attribute(name)
795		}
796	}
797
798	/// Remove all attributes from the element.
799	pub fn clear_attributes(&mut self) -> Result<()> {
800		let ok = (_API.SciterClearAttributes)(self.he);
801		ok_or!((), ok)
802	}
803
804
805	//\name Style Attributes
806
807	/// Get [style attribute](https://sciter.com/docs/content/sciter/Style.htm) of the element by its name.
808	pub fn get_style_attribute(&self, name: &str) -> String {
809		let mut s = String::new();
810		let name = s2u!(name);
811		(_API.SciterGetStyleAttributeCB)(self.he, name.as_ptr(), store_wstr, &mut s as *mut String as LPVOID);
812		return s;
813	}
814
815	/// Set [style attribute](https://sciter.com/docs/content/sciter/Style.htm).
816	pub fn set_style_attribute(&mut self, name: &str, value: &str) -> Result<()> {
817		let name = s2u!(name);
818		let value = s2w!(value);
819		let ok = (_API.SciterSetStyleAttribute)(self.he, name.as_ptr(), value.as_ptr());
820		ok_or!((), ok)
821	}
822
823	//\name State methods
824
825
826	//\name DOM tree access
827
828	/// Get index of this element in its parent collection.
829	pub fn index(&self) -> usize {
830		let mut n = 0u32;
831		(_API.SciterGetElementIndex)(self.he, &mut n as *mut UINT);
832		return n as usize;
833	}
834
835	/// Get root of the element.
836	pub fn root(&self) -> Element {
837		if let Some(dad) = self.parent() {
838			dad.root()
839		} else {
840			self.clone()
841		}
842	}
843
844	/// Get parent element.
845	pub fn parent(&self) -> Option<Element> {
846		let mut p = HELEMENT!();
847		(_API.SciterGetParentElement)(self.he, &mut p);
848		if p.is_null() {
849			None
850		} else {
851			Some(Element::from(p))
852		}
853	}
854
855	/// Get first sibling element.
856	pub fn first_sibling(&self) -> Option<Element> {
857		if let Some(dad) = self.parent() {
858			let count = dad.len();
859			if count > 0 {
860				return dad.child(0);
861			}
862		}
863		None
864	}
865
866	/// Get last sibling element.
867	pub fn last_sibling(&self) -> Option<Element> {
868		if let Some(dad) = self.parent() {
869			let count = dad.len();
870			if count > 0 {
871				return dad.child(count - 1);
872			}
873		}
874		None
875	}
876
877	/// Get next sibling element.
878	pub fn next_sibling(&self) -> Option<Element> {
879		let idx = self.index() + 1;
880		if let Some(dad) = self.parent() {
881			let count = dad.len();
882			if idx < count {
883				return dad.child(idx);
884			}
885		}
886		None
887	}
888
889	/// Get previous sibling element.
890	pub fn prev_sibling(&self) -> Option<Element> {
891		let idx = self.index();
892		if let Some(dad) = self.parent() {
893			let count = dad.len();
894			if idx > 0 && (idx - 1) < count {
895				return dad.child(idx - 1);
896			}
897		}
898		None
899	}
900
901	/// Get first child element.
902	pub fn first_child(&self) -> Option<Element> {
903		return self.child(0);
904	}
905
906	/// Get last child element.
907	pub fn last_child(&self) -> Option<Element> {
908		let count = self.len();
909		if count > 0 {
910			return self.child(count - 1);
911		}
912		None
913	}
914
915	/// Get element's child at specified index.
916	pub fn get(&self, index: usize) -> Option<Element> {
917		return self.child(index);
918	}
919
920	/// An iterator over the direct children of a DOM element.
921	pub fn children(&self) -> Children {
922		Children {
923			base: self,
924			index: 0,
925			count: self.children_count(),
926		}
927	}
928
929	/// Get element's child at specified index.
930	pub fn child(&self, index: usize) -> Option<Element> {
931		let mut p = HELEMENT!();
932		let ok = (_API.SciterGetNthChild)(self.he, index as UINT, &mut p);
933		match ok {
934			SCDOM_RESULT::OK => Some(Element::from(p)),
935			_ => None
936		}
937	}
938
939	/// Get number of child elements.
940	pub fn children_count(&self) -> usize {
941		let mut n = 0u32;
942		(_API.SciterGetChildrenCount)(self.he, &mut n as *mut UINT);
943		return n as usize;
944	}
945
946	/// Get number of child elements.
947	pub fn len(&self) -> usize {
948		return self.children_count();
949	}
950
951	/// Returns `true` is `self` has zero elements.
952	pub fn is_empty(&self) -> bool {
953		self.len() == 0
954	}
955
956	/// Clear content of the element.
957	pub fn clear(&mut self) -> Result<()> {
958		let ok = (_API.SciterSetElementText)(self.he, ::std::ptr::null(), 0);
959		ok_or!((), ok)
960	}
961
962	/// Create new element as copy of existing element.
963	///
964	/// The new element is a full (deep) copy of the element and is initially disconnected from the DOM.
965	/// Note that [`Element.clone()`](struct.Element.html#impl-Clone) does not clone the DOM element,
966	/// just increments its reference count.
967	pub fn clone_element(&self) -> Element {
968		let mut e = Element { he: HELEMENT!() };
969		(_API.SciterCloneElement)(self.he, &mut e.he);
970		return e;
971	}
972
973	/// Insert element at `index` position of this element.
974	///
975	/// Note that we cannot follow Rust semantic here
976	/// because the newly created `Element` is unusable before it will be inserted at DOM.
977	pub fn insert(&mut self, index: usize, child: &Element) -> Result<()> {
978		let ok = (_API.SciterInsertElement)(child.he, self.he, index as UINT);
979		ok_or!((), ok)
980	}
981
982	/// Append element as last child of this element.
983	pub fn append(&mut self, child: &Element) -> Result<()> {
984		self.insert(0x7FFF_FFFF, child)
985	}
986
987	/// Append element as last child of this element.
988	#[allow(clippy::needless_pass_by_value)]
989	pub fn push(&mut self, element: Element) {
990		self.append(&element).expect("Could not append element.");
991	}
992
993	/// Remove the last child from this element and returns it, or `None` if this element is empty.
994	pub fn pop(&mut self) -> Option<Element> {
995		let count = self.len();
996		if count > 0 {
997			if let Some(mut child) = self.get(count - 1) {
998				child.detach().expect("Could not detach element.");
999				return Some(child);
1000			}
1001		}
1002		return None;
1003	}
1004
1005	/// Take element out of its container (and DOM tree).
1006	pub fn detach(&mut self) -> Result<()> {
1007		let ok = (_API.SciterDetachElement)(self.he);
1008		ok_or!((), ok)
1009	}
1010
1011	/// Take element out of its container (and DOM tree) and force destruction of all behaviors.
1012	pub fn destroy(&mut self) -> Result<()> {
1013		let mut p = HELEMENT!();
1014		::std::mem::swap(&mut self.he, &mut p);
1015		let ok = (_API.SciterDeleteElement)(p);
1016		ok_or!((), ok)
1017	}
1018
1019	/// Swap element positions.
1020	pub fn swap(&mut self, other: &mut Element) -> Result<()> {
1021		let ok = (_API.SciterSwapElements)(self.he, other.he);
1022		ok_or!((), ok)
1023	}
1024
1025	//\name Selectors
1026
1027	/// Test this element against CSS selector(s).
1028	pub fn test(&self, selector: &str) -> bool {
1029		let mut p = HELEMENT!();
1030		let s = s2u!(selector);
1031		(_API.SciterSelectParent)(self.he, s.as_ptr(), 1, &mut p);
1032		return !p.is_null();
1033	}
1034
1035	/// Call specified function for every element in a DOM that meets specified CSS selectors.
1036	fn select_elements<T: ElementVisitor>(&self, selector: &str, callback: T) -> Result<Vec<Element>> {
1037		extern "system" fn inner<T: ElementVisitor>(he: HELEMENT, param: LPVOID) -> BOOL {
1038      let p = param as *mut T;
1039			let obj = unsafe { &mut *p };
1040			let e = Element::from(he);
1041			let stop = obj.on_element(e);
1042			return stop as BOOL;
1043		}
1044		let s = s2u!(selector);
1045		let handler = Box::new(callback);
1046    let param = Box::into_raw(handler);
1047		let ok = (_API.SciterSelectElements)(self.he, s.as_ptr(), inner::<T>, param as LPVOID);
1048    let handler = unsafe { Box::from_raw(param) };
1049		if ok != SCDOM_RESULT::OK {
1050			return Err(ok);
1051		}
1052		return Ok(handler.result());
1053	}
1054
1055	/// Will find first parent element starting from this satisfying given css selector(s).
1056	pub fn find_nearest_parent(&self, selector: &str) -> Result<Option<Element>> {
1057		let mut p = HELEMENT!();
1058		let s = s2u!(selector);
1059		let ok = (_API.SciterSelectParent)(self.he, s.as_ptr(), 0, &mut p);
1060		if ok != SCDOM_RESULT::OK {
1061			return Err(ok);
1062		}
1063		if p.is_null() { Ok(None) } else { Ok(Some(Element::from(p))) }
1064	}
1065
1066	/// Will find first element starting from this satisfying given css selector(s).
1067	pub fn find_first(&self, selector: &str) -> Result<Option<Element>> {
1068		let cb = FindFirstElement::default();
1069		let all = self.select_elements(selector, cb);
1070		all.map(|mut x| { x.pop() })
1071	}
1072
1073	/// Will find all elements starting from this satisfying given css selector(s).
1074	pub fn find_all(&self, selector: &str) -> Result<Option<Vec<Element>>> {
1075		let cb = FindAllElements::default();
1076		let all = self.select_elements(selector, cb);
1077		all.map(Some)
1078	}
1079
1080	//\name Scroll methods:
1081
1082	//\name Other methods:
1083
1084	/// Apply changes and refresh element area in its window.
1085	pub fn update(&self, render_now: bool) -> Result<()> {
1086		let ok = (_API.SciterUpdateElement)(self.he, render_now as BOOL);
1087		ok_or!((), ok)
1088	}
1089
1090	/// Refresh element area in its window.
1091	///
1092	/// If the element has drawing behavior attached it will receive [`on_draw`](event/trait.EventHandler.html#method.on_draw) call after that.
1093	pub fn refresh(&self) -> Result<()> {
1094		let rect = self.get_location(ELEMENT_AREAS::self_content())?;
1095		let ok = (_API.SciterRefreshElementArea)(self.he, rect);
1096		ok_or!((), ok)
1097	}
1098
1099	/// Start Timer for the element.
1100	///
1101	/// Element will receive [`on_timer`](event/trait.EventHandler.html#method.on_timer) events.
1102	///
1103	/// Note that timer events are not bubbling, so you need attach handler to the target element directly.
1104	pub fn start_timer(&self, period_ms: u32, timer_id: u64) -> Result<()> {
1105		let ok = (_API.SciterSetTimer)(self.he, period_ms as UINT, timer_id as ::capi::sctypes::UINT_PTR);
1106		ok_or!((), ok)
1107	}
1108
1109	/// Stop Timer for the element.
1110	pub fn stop_timer(&self, timer_id: u64) -> Result<()> {
1111		if !self.he.is_null() {
1112			let ok = (_API.SciterSetTimer)(self.he, 0, timer_id as ::capi::sctypes::UINT_PTR);
1113			ok_or!((), ok)
1114		} else {
1115			Ok(())
1116		}
1117	}
1118
1119	/// Attach the native event handler to this element.
1120	pub fn attach_handler<Handler: EventHandler>(&mut self, handler: Handler) -> Result<u64> {
1121		// make native handler
1122		let boxed = Box::new(handler);
1123		let ptr = Box::into_raw(boxed);	// dropped in `_event_handler_proc`
1124		let token = ptr as usize as u64;
1125		let ok = (_API.SciterAttachEventHandler)(self.he, ::eventhandler::_event_handler_proc::<Handler>, ptr as LPVOID);
1126		ok_or!(token, ok)
1127	}
1128
1129	/// Detach your handler from the element. Handlers identified by `token` from `attach_handler()` result.
1130	pub fn detach_handler<Handler: EventHandler>(&mut self, token: u64) -> Result<()> {
1131		let ptr = token as usize as *mut Handler;
1132		let ok = (_API.SciterDetachEventHandler)(self.he, ::eventhandler::_event_handler_proc::<Handler>, ptr as LPVOID);
1133		ok_or!((), ok)
1134	}
1135}
1136
1137/// Release element pointer.
1138impl Drop for Element {
1139	fn drop(&mut self) {
1140		(_API.Sciter_UnuseElement)(self.he);
1141		self.he = HELEMENT!();
1142	}
1143}
1144
1145/// Increment reference count of the dom element.
1146impl Clone for Element {
1147	fn clone(&self) -> Self {
1148		Element::from(self.he)
1149	}
1150}
1151
1152/// Human element representation.
1153impl ::std::fmt::Display for Element {
1154	fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
1155		if self.he.is_null() {
1156			return f.write_str("None");
1157		}
1158		// "tag#id.class|type(name)"
1159		// "tag#id.class"
1160
1161    let tag = self.get_tag();
1162		f.write_str(&tag)?;
1163
1164		if let Some(i) = self.get_attribute("id") {
1165			write!(f, "#{}", i)?;
1166		}
1167    if let Some(c) = self.get_attribute("class") {
1168			write!(f, ".{}", c)?;
1169		}
1170    if let Some(t) = self.get_attribute("type") {
1171			write!(f, "|{}", t)?;
1172		}
1173    if let Some(n) = self.get_attribute("name") {
1174			write!(f, "({})", n)?;
1175		}
1176		return Ok(());
1177	}
1178}
1179
1180/// Machine-like element visualization (`{:?}` and `{:#?}`).
1181impl ::std::fmt::Debug for Element {
1182	fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
1183		if f.alternate() {
1184			use ::std::mem;
1185
1186			fn state_name(value: &ELEMENT_STATE_BITS) -> &'static str {
1187				match *value {
1188					ELEMENT_STATE_BITS::STATE_LINK => "link",
1189					ELEMENT_STATE_BITS::STATE_HOVER => "hover",
1190					ELEMENT_STATE_BITS::STATE_ACTIVE => "active",
1191					ELEMENT_STATE_BITS::STATE_VISITED => "visited",
1192					ELEMENT_STATE_BITS::STATE_FOCUS => "focus",
1193					ELEMENT_STATE_BITS::STATE_POPUP => "popup",
1194					ELEMENT_STATE_BITS::STATE_CURRENT => "current",
1195					ELEMENT_STATE_BITS::STATE_CHECKED => "checked",
1196					ELEMENT_STATE_BITS::STATE_EXPANDED => "expanded",
1197					ELEMENT_STATE_BITS::STATE_COLLAPSED => "collapsed",
1198					ELEMENT_STATE_BITS::STATE_DISABLED => "disabled",
1199					ELEMENT_STATE_BITS::STATE_INCOMPLETE => "incomplete",
1200					ELEMENT_STATE_BITS::STATE_BUSY => "busy",
1201					ELEMENT_STATE_BITS::STATE_ANIMATING => "animating",
1202					ELEMENT_STATE_BITS::STATE_FOCUSABLE => "",
1203					ELEMENT_STATE_BITS::STATE_READONLY => "readonly",
1204					ELEMENT_STATE_BITS::STATE_EMPTY => "empty",
1205					ELEMENT_STATE_BITS::STATE_ANCHOR => "anchor",
1206					ELEMENT_STATE_BITS::STATE_SYNTHETIC => "synthetic",
1207					ELEMENT_STATE_BITS::STATE_OWNS_POPUP => "owns_popup",
1208					ELEMENT_STATE_BITS::STATE_TABFOCUS => "tabfocus",
1209					ELEMENT_STATE_BITS::STATE_IS_RTL => "is_rtl",
1210					ELEMENT_STATE_BITS::STATE_IS_LTR => "is_ltr",
1211					ELEMENT_STATE_BITS::STATE_DRAG_OVER => "drag_over",
1212					ELEMENT_STATE_BITS::STATE_DROP_TARGET => "drop_target",
1213					ELEMENT_STATE_BITS::STATE_MOVING => "moving",
1214					ELEMENT_STATE_BITS::STATE_COPYING => "copying",
1215					ELEMENT_STATE_BITS::STATE_DRAG_SOURCE => "drag_source",
1216					ELEMENT_STATE_BITS::STATE_DROP_MARKER => "drop_marker",
1217
1218					ELEMENT_STATE_BITS::STATE_READY => "",
1219					ELEMENT_STATE_BITS::STATE_PRESSED => "pressed",
1220
1221					ELEMENT_STATE_BITS::STATE_NONE => "",
1222				}
1223			}
1224
1225			// "tag#id.class:state1:state2..."
1226			let state = self.get_state() as u32;
1227
1228			write!(f, "{{{}", self)?;
1229			for i in 0..31 {
1230				let bit = state & (1 << i);
1231				if bit != 0 {
1232					let state_bit: ELEMENT_STATE_BITS = unsafe { mem::transmute(bit) };
1233					let name = state_name(&state_bit);
1234					if !name.is_empty() {
1235						write!(f, ":{}", name)?;
1236					}
1237				}
1238			}
1239			write!(f, "}}")
1240
1241		} else {
1242			// "tag#id.class(name):0xdfdfdf"
1243			write!(f, "{{{}:{:?}}}", self, self.he)
1244		}
1245	}
1246}
1247
1248
1249/// An iterator over the direct children of a DOM element.
1250pub struct Children<'a> {
1251	base: &'a Element,
1252	index: usize,
1253	count: usize,
1254}
1255
1256/// Allows `for child in el.children() {}` enumeration.
1257impl<'a> ::std::iter::Iterator for Children<'a> {
1258	type Item = Element;
1259
1260	fn next(&mut self) -> Option<Element> {
1261		if self.index < self.count {
1262			let pos = self.index;
1263			self.index += 1;
1264			self.base.child(pos)
1265		} else {
1266			None
1267		}
1268	}
1269
1270	fn size_hint(&self) -> (usize, Option<usize>) {
1271		let remain = self.count - self.index;
1272		(remain, Some(remain))
1273	}
1274
1275	fn count(self) -> usize {
1276		self.count
1277	}
1278}
1279
1280impl<'a> ::std::iter::DoubleEndedIterator for Children<'a> {
1281	fn next_back(&mut self) -> Option<Element> {
1282		if self.index == self.count || self.count == 0 {
1283			None
1284		} else {
1285			self.count -= 1;
1286			self.base.child(self.count)
1287		}
1288	}
1289}
1290
1291/// Allows `for child in &el {}` enumeration.
1292impl<'a> ::std::iter::IntoIterator for &'a Element {
1293	type Item = Element;
1294	type IntoIter = Children<'a>;
1295
1296	fn into_iter(self) -> Children<'a> {
1297		self.children()
1298	}
1299}
1300
1301
1302/* Not implemented yet or not used APIs:
1303
1304SciterCallBehaviorMethod
1305SciterCombineURL
1306SciterControlGetType
1307SciterGetElementIntrinsicHeight
1308SciterGetElementIntrinsicWidths
1309SciterGetElementLocation
1310SciterGetElementNamespace
1311SciterGetElementType
1312SciterGetExpando
1313SciterGetObject
1314SciterGetScrollInfo
1315SciterHidePopup
1316SciterHttpRequest
1317SciterIsElementEnabled
1318SciterIsElementVisible
1319SciterReleaseCapture
1320SciterRequestElementData
1321SciterScrollToView
1322SciterSetCapture
1323SciterSetHighlightedElement
1324SciterSetScrollPos
1325SciterShowPopup
1326SciterShowPopupAt
1327SciterSortElements
1328SciterTraverseUIEvent
1329
1330SciterCreateCommentNode
1331SciterCreateTextNode
1332SciterNodeAddRef
1333SciterNodeCastFromElement
1334SciterNodeCastToElement
1335SciterNodeChildrenCount
1336SciterNodeFirstChild
1337SciterNodeGetText
1338SciterNodeInsert
1339SciterNodeLastChild
1340SciterNodeNextSibling
1341SciterNodeNthChild
1342SciterNodeParent
1343SciterNodePrevSibling
1344SciterNodeRelease
1345SciterNodeRemove
1346SciterNodeSetText
1347SciterNodeType
1348
1349*/
1350
1351pub mod event {
1352	//!
1353	//! Behaviors support (a.k.a windowless controls).
1354	//!
1355	/*!
1356
1357# Behaviors and event handling.
1358
1359The primary goal of the User Interface (UI) as a subsystem is to present some information to the user
1360and generate some events according to user’s actions.
1361Your application handles UI events and acts accordingly executing its functions.
1362
1363To be able to handle events in native code you will need to attach an instance of
1364[`sciter::EventHandler`](trait.EventHandler.html)
1365to an existing DOM element or to the window itself.
1366In `EventHandler`'s implementation you will receive all events
1367dispatched to the element and its children as before children (in [`PHASE_MASK::SINKING`](enum.PHASE_MASK.html) phase)
1368as after them ([`PHASE_MASK::BUBBLING`](enum.PHASE_MASK.html) event phase),
1369see [Events Propagation](https://sciter.com/developers/for-native-gui-programmers/#events-propagation).
1370
1371`EventHandler` attached to the window will receive all DOM events no matter which element they are targeted to.
1372
1373`EventHandler` contains [various methods](trait.EventHandler.html#provided-methods) –
1374receivers of events of various types.
1375You can override any of these methods in order to receive events you are interested in
1376in your implementation of `sciter::EventHandler`.
1377
1378
1379To attach a native event handler to a DOM element or to the window you can do one of these:
1380
1381* "Manually", to a Sciter window: `sciter::Window.event_handler(your_event_handler)`
1382* "Manually", to an arbitrary DOM element: `sciter::dom::Element.attach_handler(your_event_handler)`
1383* To a group of DOM elements by declaration in CSS: `selector { behavior:your-behavior-name }`
1384
1385You also can assign events handlers defined in script code:
1386
1387* "Manually", individual events: if you have a reference `el` of some element then
1388to handle mouse events you can do this, for example:
1389
1390```tiscript
1391el.onMouse = function(evt) { ... }
1392```
1393
1394* "Manually", by assigning a behavior class to the [Element](https://sciter.com/docs/content/sciter/Element.htm):
1395
1396```tiscript
1397class MyEventsHandler: Element { ... }  // your behavior class which inherits sciter's Element class
1398el.prototype = MyEventsHandler; // "sub-class" the element.
1399```
1400
1401* By declaration in CSS - to all elements satisfying some CSS selector:
1402
1403```css
1404selector { prototype: MyEventsHandler; }
1405```
1406
1407In this case `MyEventsHandler` class should be defined in one of script files loaded by your HTML.
1408
1409See the **Behavior attributes** section of [Sciter CSS property map](https://sciter.com/docs/content/css/cssmap.html)
1410and [this blog article](http://www.terrainformatica.com/2014/07/sciter-declarative-behavior-assignment-by-css-prototype-and-aspect-properties/) which covers
1411Behaviors, Prototypes and Aspects of Sciter CSS behavior assignment.
1412
1413
1414
1415
1416
1417# Script and native code interaction
1418
1419
1420In Sciter you may want to define native functions that can be called by script.
1421At the same time you may need to call script functions from native code.
1422Sciter supports such interaction providing set of simple API functions:
1423
1424## Evaluating scripts and invoking script functions from native code
1425
1426You can use one of these methods to call scripts from code of your application:
1427
1428* To evaluate arbitrary script in context of current document loaded into the window:
1429
1430```rust,no_run
1431# use sciter::dom::Element;
1432# use sciter::Value;
1433# let hwnd = ::std::ptr::null_mut();
1434let root = Element::from_window(hwnd).unwrap();
1435let result: Value = root.eval_script("... script ...").unwrap();
1436```
1437
1438* To call a global function defined in script using its full name (may include the name of namespaces where it resides):
1439
1440```ignore
1441# #[macro_use] extern crate sciter;
1442# use sciter::Value;
1443# let root = sciter::dom::Element::from(::std::ptr::null_mut());
1444let result: Value = root.call_function("namespace.name", &make_args!(1, "2", 3.0)).unwrap();
1445```
1446The parameters are passed as a `&[Value]` slice.
1447
1448* To call a method (function) defined in script for particular DOM element:
1449
1450```ignore
1451# #[macro_use] extern crate sciter;
1452# use sciter::Value;
1453# let root = sciter::dom::Element::from(::std::ptr::null_mut());
1454if let Some(el) = root.find_first("input").unwrap() {
1455  let result: Value = el.call_method("canUndo", &make_args!()).unwrap();
1456}
1457```
1458
1459
1460## Calling native code from script
1461
1462If needed, your application may expose some [native] functions to be called by script code.
1463Usually this is made by implementing your own `EventHandler` and overriding its `on_script_call` method.
1464If you do this, then you can invoke this callback from script as:
1465
1466* "global" native functions: `var r = view.funcName( p0, p1, ... );` – calling
1467`on_script_call` of an `EventHandler` instance attached to the **window**.
1468* As element’s methods: `var r = el.funcName( p0, p1, ... );` – calling
1469`on_script_call` of an `EventHandler` instance (native behavior) attached to the **element**.
1470
1471This way you can establish interaction between scipt and native code inside your application.
1472
1473*/
1474
1475	pub use capi::scbehavior::{EVENT_GROUPS, BEHAVIOR_EVENTS, PHASE_MASK};
1476  pub use capi::scbehavior::{CLICK_REASON, EDIT_CHANGED_REASON, DRAW_EVENTS};
1477
1478	use capi::sctypes::*;
1479	use capi::scdom::HELEMENT;
1480	use capi::scgraphics::HGFX;
1481	use value::Value;
1482
1483	/// Default subscription events.
1484	///
1485	/// Default are `HANDLE_BEHAVIOR_EVENT | HANDLE_SCRIPTING_METHOD_CALL | HANDLE_METHOD_CALL` which cover behavior events
1486	/// (like `document_complete` or `button_click`) and TIScript/JavaScript calls to native window.
1487	pub fn default_events() -> EVENT_GROUPS {
1488		return EVENT_GROUPS::HANDLE_BEHAVIOR_EVENT | EVENT_GROUPS::HANDLE_SCRIPTING_METHOD_CALL | EVENT_GROUPS::HANDLE_METHOD_CALL;
1489	}
1490
1491	/// UI action causing change.
1492	#[derive(Debug)]
1493	pub enum EventReason {
1494		/// General event source triggers (by mouse, key or synthesized).
1495		General(CLICK_REASON),
1496		/// Edit control change trigger.
1497		EditChanged(EDIT_CHANGED_REASON),
1498		/// `<video>` request for frame source binding.
1499    ///
1500    /// See the [`sciter::video`](../../video/index.html) module for more reference.
1501		VideoBind(LPVOID),
1502	}
1503
1504  /// Behavior method params.
1505  ///
1506  /// Sciter sends these events to native behaviors.
1507  #[derive(Debug)]
1508  pub enum MethodParams<'a> {
1509    /// Click event (either from mouse or code).
1510    Click,
1511
1512    /// Get current [`:empty`](https://sciter.com/docs/content/sciter/States.htm) state,
1513    /// i.e. if behavior has no children and no text.
1514    IsEmpty(&'a mut bool),
1515
1516    /// Get the current value of the behavior.
1517    GetValue(&'a mut Value),
1518
1519    /// Set the current value of the behavior.
1520    SetValue(Value),
1521
1522    /// Custom methods, unknown for engine. Sciter will not intrepret it and will do just dispatching.
1523    Custom(u32, LPVOID),
1524  }
1525
1526
1527	/// DOM event handler which can be attached to any DOM element.
1528	///
1529	/// In notifications:
1530	///
1531	/// * `root` means the DOM element to which we are attached (`<html>` for `Window` event handlers).
1532	/// * `target` contains a reference to the notification target DOM element.
1533	/// * `source` element e.g. in `SELECTION_CHANGED` it is the new selected `<option>`,
1534	/// in `MENU_ITEM_CLICK` it is a menu item (`<li>`) element.
1535	///
1536	/// For example, if we are attached to the `<body>` element,
1537	/// we will receive `document_complete` with `target` set to `<html>`.
1538	///
1539	#[allow(unused_variables)]
1540	pub trait EventHandler {
1541
1542		/// Return a list of event groups this event handler is subscribed to.
1543		///
1544		/// Default are `HANDLE_BEHAVIOR_EVENT | HANDLE_SCRIPTING_METHOD_CALL | HANDLE_METHOD_CALL`.
1545		/// See also [`default_events()`](fn.default_events.html).
1546		fn get_subscription(&mut self) -> Option<EVENT_GROUPS> {
1547			return Some(default_events());
1548		}
1549
1550		/// Called when handler was attached to element or window.
1551		/// `root` is `NULL` if attaching to window without loaded document.
1552    ///
1553    /// **Subscription**: always.
1554		fn attached(&mut self, root: HELEMENT) {}
1555
1556		/// Called when handler was detached from element or window.
1557    ///
1558    /// **Subscription**: always.
1559		fn detached(&mut self, root: HELEMENT) {}
1560
1561		/// Notification that document finishes its loading - all requests for external resources are finished.
1562    ///
1563    /// **Subscription**: requires [`HANDLE_BEHAVIOR_EVENT`](enum.EVENT_GROUPS.html),
1564    /// but will be sent only for the root element (`<html>`).
1565		fn document_complete(&mut self, root: HELEMENT, target: HELEMENT) {}
1566
1567		/// The last notification before document removal from the DOM.
1568    ///
1569    /// **Subscription**: requires [`HANDLE_BEHAVIOR_EVENT`](enum.EVENT_GROUPS.html),
1570    /// but will be sent only for the root element (`<html>`).
1571		fn document_close(&mut self, root: HELEMENT, target: HELEMENT) {}
1572
1573    /// Behavior method calls from script or other behaviors.
1574    ///
1575    /// Return `false` to skip this event.
1576    ///
1577    /// **Subscription**: requires [`HANDLE_METHOD_CALL`](enum.EVENT_GROUPS.html).
1578    fn on_method_call(&mut self, root: HELEMENT, params: MethodParams) -> bool { return false }
1579
1580		/// Script calls from CSSS! script and TIScript.
1581    ///
1582    /// Return `None` to skip this event.
1583    ///
1584    /// **Subscription**: requires [`HANDLE_SCRIPTING_METHOD_CALL`](enum.EVENT_GROUPS.html).
1585		fn on_script_call(&mut self, root: HELEMENT, name: &str, args: &[Value]) -> Option<Value> {
1586			return self.dispatch_script_call(root, name, args);
1587		}
1588
1589		/// Autogenerated dispatcher for script calls.
1590    #[doc(hidden)]
1591		fn dispatch_script_call(&mut self, root: HELEMENT, name: &str, args: &[Value]) -> Option<Value> {
1592			return None;
1593		}
1594
1595		/// Return the reference to a native asset assotiated with behavior.
1596		#[doc(hidden)]
1597		fn get_asset(&mut self) -> Option<&crate::capi::scom::som_asset_t> {
1598			// TODO: is this good?
1599			return None;
1600		}
1601
1602		/// Notification event from builtin behaviors.
1603    ///
1604    /// Return `false` to skip this event.
1605    ///
1606    /// **Subscription**: requires [`HANDLE_BEHAVIOR_EVENT`](enum.EVENT_GROUPS.html).
1607		fn on_event(&mut self, root: HELEMENT, source: HELEMENT, target: HELEMENT, code: BEHAVIOR_EVENTS, phase: PHASE_MASK, reason: EventReason) -> bool {
1608			return false;
1609		}
1610
1611		/// Timer event from attached element.
1612    ///
1613    /// Return `false` to skip this event.
1614    ///
1615    /// **Subscription**: requires [`HANDLE_TIMER`](enum.EVENT_GROUPS.html).
1616		fn on_timer(&mut self, root: HELEMENT, timer_id: u64) -> bool { return false; }
1617
1618		/// Drawing request event.
1619		///
1620		/// It allows to intercept drawing events of an `Element` and to manually draw its content, background and foreground layers.
1621    ///
1622    /// Return `false` to skip this event.
1623    ///
1624    /// **Subscription**: requires [`HANDLE_DRAW`](enum.EVENT_GROUPS.html).
1625		fn on_draw(&mut self, root: HELEMENT, gfx: HGFX, area: &RECT, layer: DRAW_EVENTS) -> bool { return false; }
1626
1627		/// Size changed event.
1628    ///
1629    /// **Subscription**: requires [`HANDLE_SIZE`](enum.EVENT_GROUPS.html).
1630		fn on_size(&mut self, root: HELEMENT) {}
1631	}
1632
1633}