void checkall (dom::element& table, bool onOff ) { if( !is_multiple(table) ) return; struct unchecker_cb: dom::callback { bool on_element(HELEMENT he) { htmlayout::dom::element el = he; if( el.get_state(STATE_CHECKED)) el.set_state(0,STATE_CHECKED,false ); return false; /*continue enumeration*/ } }; struct checker_cb: dom::callback { bool on_element(HELEMENT he) { htmlayout::dom::element el = he; if( !el.get_state(STATE_CHECKED)) el.set_state(STATE_CHECKED,0,false ); return false; /*continue enumeration*/ } }; if(onOff) { checker_cb checker; table.find_all(&checker,"tr"); } else { unchecker_cb unchecker; table.find_all(&unchecker,"tr:checked"); } }
/** Get values of all "controls" contained inside the DOM element. * Function will gather values of elements having name attribute defined * and recognized by get_ctl_type() function. * \param[in] el \b dom::element&, The element. * \param[out] all \b named_values&, Collection. * \return \b bool, \c true if there are any value was harvested. **/ inline bool get_values(const dom::element& el, named_values& all ) { selected_cb selected; el.find_all(&selected, "[name]" ); // select all elements having name attribute for( unsigned int n = 0; n < selected.elements.size(); ++n ) { const dom::element& t = selected.elements[n]; //if( !t.get_style_attribute("behavior") ) // continue; - commented out to support input type="hidden" that does not have behavior assigned const wchar_t* pn = t.get_attribute("name"); if( !pn ) { assert(false); // how come? continue; } std::wstring name = pn; if( all.find(name) != all.end()) continue; // element with this name is already there, // checkboxes and radios are groups in fact, // we are returning here only cumulative group value int ctl_type = get_ctl_type(t); if( ctl_type == CTL_NO/*|| ctl_type == CTL_BUTTON*/) continue; all[name] = get_value(selected.elements[n]); } return all.size() != 0; }
static BOOL process_key( dom::element& container, const char* keyname ) { // find all callback struct:public htmlayout::dom::callback { htmlayout::dom::element hot_key_element; virtual bool on_element(HELEMENT he) { htmlayout::dom::element t = he; if( t.enabled() && t.visible()) { hot_key_element = t; return true; // found, stop; } return false; } } cb; //Original version was: // container.find_all(&cb, "[accesskey=='%s']", keyname); //By request of Christopher Brown, the Great, from Symantec this became as: container.find_all(&cb, "[accesskey=='%s'],[accesskey-alt=='%s']", keyname, keyname); if( cb.hot_key_element.is_valid()) { METHOD_PARAMS prm; prm.methodID = DO_CLICK; if(cb.hot_key_element.call_behavior_method(&prm)) return true; } return false; }
// selects all options in multiselect. inline void select_all_options(dom::element& select_el ) { selected_cb all_options; select_el.find_all(&all_options, "option"); // select all currently selected <option>s for( int n = int(all_options.elements.size()) - 1; n >= 0 ; --n ) all_options.elements[n].set_state(STATE_CHECKED,0, false); // set state select_el.update(); }
// clear checked states in multiselect <select>. // this simply resets :checked state for all checked <option>'s inline void clear_all_options(dom::element& select_el ) { selected_cb selected; select_el.find_all(&selected, "option:checked,[role='option']:checked"); // select all currently selected <option>s for( int n = int(selected.elements.size()) - 1; n >= 0 ; --n ) selected.elements[n].set_state(0, STATE_CHECKED, false); // reset state select_el.update(); }
// the same as above but for arbitrary root/name inline void set_radio_index( dom::element root, const char* name, unsigned int idx ) { selected_cb selected; root.find_all(&selected, "[type='radio'][name='%S']", name); for( unsigned int n = 0; n < selected.elements.size(); ++n ) { dom::element& e = selected.elements[n]; if ( n == idx) { e.set_value(json::value(true)); break; } } }
static BOOL process_key( dom::element& container, const char* keyname ) { // find all callback struct:public htmlayout::dom::callback { htmlayout::dom::element hot_key_element; virtual bool on_element(HELEMENT he) { htmlayout::dom::element t = he; if( !t.enabled() ) return false; if( t.test("menu>li") ) { hot_key_element = t; return true; // found, stop; } if(t.visible()) { hot_key_element = t; return true; // found, stop; } return false; } } cb; //Original version was: // container.find_all(&cb, "[accesskey=='%s']", keyname); //By request of Christopher Brown, the Great, from Symantec this became as: container.find_all(&cb, "[accesskey=='%s'],[accesskey-alt=='%s']", keyname, keyname); if( cb.hot_key_element.is_valid()) { METHOD_PARAMS prm; prm.methodID = DO_CLICK; //cb.hot_key_element.set_state(STATE_FOCUS); if(cb.hot_key_element.call_behavior_method(&prm)) return true; // accesskey is defined for the element but it does not // handle DO_CLICK. Ask parents to activate it. // See behavior_tabs.cpp... htmlayout::dom::element hot_element_parent = cb.hot_key_element.parent(); return hot_element_parent.send_event(ACTIVATE_CHILD,0, cb.hot_key_element); } return false; }
//toggles checkmark void toggle_checkmark( dom::element select, dom::element item ) { const wchar_t* _old_state = item.get_attribute(CHECK_ATTR); std::wstring old_state = _old_state?_old_state:L""; if( streq(item.get_element_type(), "options")) { // non-terminal node case // inner function struct child_toggler: dom::callback { const wchar_t* state; child_toggler(const wchar_t* st): state(st) {} inline bool on_element(HELEMENT he) { htmlayout::dom::element item = he; item.set_attribute( CHECK_ATTR, state ); return false; } }; const wchar_t* new_state; NODE_STATE old_state = get_state(item); if(old_state == NODE_OFF) new_state = L"on"; else new_state = L"off"; child_toggler ct( new_state ); // do it for all children item.find_all(&ct, "option,options"); // and for itself item.set_attribute( CHECK_ATTR, new_state ); item.update(); } else if( streq(item.get_element_type(), "option")) { // terminal node const wchar_t* new_state; if(wcseq(item.get_attribute("check"),L"on")) { new_state = L"off"; } else new_state = L"on"; item.set_attribute( CHECK_ATTR, new_state ); item.update(); } // as state was changed we need to update parent chain here too. dom::element p = item.parent(); while( p.is_valid() && p != select ) { if( streq(p.get_element_type(),"options" )) { setup_node(p); } p = p.parent(); } }