///|
fn Browser::set_text_control_selection_from_cells(
self : Browser,
source_id : String,
anchor_col : Int,
anchor_row : Int,
focus_col : Int,
focus_row : Int,
) -> Bool {
if !self.enable_js {
return false
}
match self.get_hit_region_for_source_id(source_id) {
Some(region) => {
let anchor_local_col = if anchor_col <= region.col {
0
} else if anchor_col >= region.col + region.width {
region.width
} else {
anchor_col - region.col
}
let anchor_local_row = if anchor_row <= region.row {
0
} else if anchor_row >= region.row + region.height {
region.height - 1
} else {
anchor_row - region.row
}
let focus_local_col = if focus_col <= region.col {
0
} else if focus_col >= region.col + region.width {
region.width
} else {
focus_col - region.col
}
let focus_local_row = if focus_row <= region.row {
0
} else if focus_row >= region.row + region.height {
region.height - 1
} else {
focus_row - region.row
}
let escaped = escape_js_string(source_id)
let source = "(function(){const target=document.getElementById('" +
escaped +
"');if(!target){return 'missing';}const tag=(target.tagName||'').toLowerCase();const type=(target.getAttribute?((target.getAttribute('type')||'').toLowerCase()):'');function isTextLikeInput(){if(tag!=='input'){return false;}return type===''||type==='text'||type==='search'||type==='url'||type==='tel'||type==='email'||type==='password'||type==='number';}function currentValue(el){if(!el){return '';}if(el.value!==undefined&&el.value!==null){return String(el.value);}if(el.getAttribute){return String(el.getAttribute('value')||'');}return '';}function setCaret(index){const value=currentValue(target);const clamped=Math.max(0,Math.min(value.length,Number(index)||0));if(typeof target.setSelectionRange==='function'){target.setSelectionRange(clamped,clamped);}else{target.selectionStart=clamped;target.selectionEnd=clamped;}return 'ok';}if(tag==='textarea'){const value=currentValue(target);const lines=value.split('\\n');const localRow=" +
anchor_local_row.to_string() +
";const anchorCol=" +
anchor_local_col.to_string() +
";const focusRow=" +
focus_local_row.to_string() +
";const focusCol=" +
focus_local_col.to_string() +
";const anchorRow=localRow;function indexForPosition(row,col){let offset=0;for(let i=0;i=row||i===lines.length-1){return offset+Math.max(0,Math.min(line.length,col));}offset+=line.length+1;}return value.length;}const anchor=indexForPosition(anchorRow,anchorCol);const focus=indexForPosition(focusRow,focusCol);const start=Math.min(anchor,focus);const end=Math.max(anchor,focus);if(typeof target.setSelectionRange==='function'){target.setSelectionRange(start,end);}else{target.selectionStart=start;target.selectionEnd=end;}return 'ok';}if(isTextLikeInput()){const value=currentValue(target);const anchor=Math.max(0,Math.min(value.length," +
anchor_local_col.to_string() +
"));const focus=Math.max(0,Math.min(value.length," +
focus_local_col.to_string() +
"));const start=Math.min(anchor,focus);const end=Math.max(anchor,focus);if(typeof target.setSelectionRange==='function'){target.setSelectionRange(start,end);}else{target.selectionStart=start;target.selectionEnd=end;}return 'ok';}return 'none';})()"
self.execute_inline_js(source) == Some("ok")
}
None => false
}
}
///|
fn Browser::set_text_control_caret_from_cell(
self : Browser,
source_id : String,
col : Int,
row : Int,
) -> Bool {
self.set_text_control_selection_from_cells(source_id, col, row, col, row)
}
///|
fn Browser::dispatch_focused_key_to_source_id(
self : Browser,
source_id : String,
key : String,
) -> FocusedKeyDispatchResult {
if !self.enable_js {
return NotHandled
}
let escaped_id = escape_js_string(source_id)
let escaped_key = escape_js_string(key)
let source = "(function(){const target=document.getElementById('" +
escaped_id +
"');const key='" +
escaped_key +
"';if(!target){return 'none';}const tag=(target.tagName||'').toLowerCase();const type=(target.getAttribute?((target.getAttribute('type')||'').toLowerCase()):'');function dispatchKeyboard(typeName,cancelable){const ev=new KeyboardEvent(typeName,{bubbles:true,cancelable,key:key});return target.dispatchEvent(ev);}function finishHandled(){dispatchKeyboard('keyup',false);return 'handled';}function finish(result){dispatchKeyboard('keyup',false);return result;}function dispatchBeforeInput(inputType,data){let event;if(typeof InputEvent==='function'){event=new InputEvent('beforeinput',{bubbles:true,cancelable:true,data,inputType});}else{event=new Event('beforeinput',{bubbles:true,cancelable:true});event.data=data;event.inputType=inputType;}return target.dispatchEvent(event);}function dispatchInput(){target.dispatchEvent(new Event('input',{bubbles:true}));}function dispatchChange(){target.dispatchEvent(new Event('change',{bubbles:true}));markChangeBase(target);}function currentValue(el){if(!el){return '';}if(el.value!==undefined&&el.value!==null){return String(el.value);}if(el.getAttribute){return String(el.getAttribute('value')||'');}return '';}function markChangeBase(el){if(!el||!el.setAttribute){return;}el.setAttribute('data-crater-change-base',currentValue(el));}function ensureDefaultValue(el){if(!el||!el.getAttribute||!el.setAttribute){return;}if(el.getAttribute('data-crater-default-value')!==null){return;}el.setAttribute('data-crater-default-value',currentValue(el));}function ensureDefaultChecked(el){if(!el||!el.getAttribute||!el.setAttribute){return;}if(el.getAttribute('data-crater-default-checked')!==null){return;}el.setAttribute('data-crater-default-checked',el.checked?'true':'false');}function syncValueAttr(el){if(el&&el.setAttribute){el.setAttribute('value',currentValue(el));}}function syncCheckedAttr(el){if(!el||!el.setAttribute){return;}if(el.checked){el.setAttribute('checked','');}else if(el.removeAttribute){el.removeAttribute('checked');}}function currentSelection(){const value=currentValue(target);const length=value.length;let start=target.selectionStart;let end=target.selectionEnd;if(start===undefined||start===null){start=length;}if(end===undefined||end===null){end=start;}start=Math.max(0,Math.min(length,Number(start)||0));end=Math.max(0,Math.min(length,Number(end)||0));if(end {
let _ = self.sync_render_state_from_dom_tree()
match result {
"handled" => Handled
"activate" => Activate
"submit" => Submit
_ => NotHandled
}
}
None => NotHandled
}
}