okami.mom/albedo
git clone https://git.nkp.pet/okami.mom/albedo
7de30f7
main
1"""Small page-side functions; values cross the boundary, not live JS handles.""" 2 3STATE = r"""function() { 4const e = this.nodeType === 1 ? this : this.parentElement; 5if (!e || !e.isConnected) return {connected:false}; 6const r = e.getBoundingClientRect(), s = getComputedStyle(e); 7return {connected:true, tag:e.tagName.toLowerCase(), type:e.type || '', 8disabled:!!e.disabled || e.getAttribute('aria-disabled') === 'true', 9readonly:!!e.readOnly || e.getAttribute('aria-readonly') === 'true', 10editable:e.isContentEditable, 11visible:r.width > 0 && r.height > 0 && s.visibility === 'visible' 12&& s.display !== 'none' && Number(s.opacity) !== 0, 13width:r.width, height:r.height}; 14}""" 15 16CONTAINS = r"""function(hit) { 17const e = this.nodeType === 1 ? this : this.parentElement; 18for (let n = hit; n; n = n.parentNode || n.host) if (n === e) return true; 19return false; 20}""" 21 22SELECT_TEXT = r"""function() { 23this.focus(); 24if (this.getRootNode().activeElement !== this) return false; 25if (typeof this.select === 'function') this.select(); 26else if (this.isContentEditable) { 27const range = this.ownerDocument.createRange(); range.selectNodeContents(this); 28const sel = this.ownerDocument.getSelection(); sel.removeAllRanges(); sel.addRange(range); 29} else return false; 30return true; 31}""" 32 33READ_VALUE = ( 34r"""function() { return this.isContentEditable ? this.textContent : this.value; }""" 35)