syntax-probe.mjs (3002B)
1 // CodeMirror document, selection, highlighting and viewport checks. 2 import {sourceEditor as editor,el,wait,status,pause} from './source-probe-helpers.mjs'; 3 const assert=(ok,message)=>{if(!ok)throw Error(message);}; 4 export async function syntaxProbe(){ 5 for(let i=0;editor.isDisabled;i++){assert(i<3600,'Source editable');await pause(25);} 6 const initiallyPublished=el('status').textContent==='Ready'; 7 const dom=editor.dom,saved=editor.getSource(),frame=()=>new Promise(r=>requestAnimationFrame(()=>requestAnimationFrame(r))); 8 assert(dom.querySelector('.syntax-definition'),'Loaded declarations highlighted'); 9 assert(dom.querySelector('[contenteditable=true][aria-label]')&&!dom.querySelector('textarea,.syntax-viewport'),'Single accessible editing surface'); 10 assert(document.querySelector('#source .syntax-definition'),'Read-only source shares tokens'); 11 const set=value=>editor.replaceSource(value,true),caret=position=>editor.select(position); 12 set('let named x = [x (t)] in named "λ🙂["'); 13 assert(dom.querySelector('.syntax-definition').textContent==='named','Local declaration color'); 14 assert(getComputedStyle(dom.querySelector('.syntax-definition')).color!==getComputedStyle(dom.querySelector('.syntax-name')).color,'Definition color'); 15 caret(editor.getSource().indexOf('['));assert(dom.querySelectorAll('.bracket-match').length===2,'Bracket pair'); 16 caret(editor.getSource().lastIndexOf('['));assert(!dom.querySelector('.bracket-match'),'String brackets ignored'); 17 editor.select(0,4);assert(!dom.querySelector('.bracket-match'),'Range has no caret match'); 18 set('(t');caret(0);assert(dom.querySelector('.bracket-unmatched'),'Unclosed delimiter'); 19 set('<img src=x onerror="throw 1">');assert(!dom.querySelector('img')&&editor.getSource()==='<img src=x onerror="throw 1">','Source markup remains literal text'); 20 dom.dispatchEvent(new CompositionEvent('compositionstart')); 21 assert(dom.classList.contains('composing'),'Composition lifecycle observed'); 22 set('"λ🙂"');dom.dispatchEvent(new CompositionEvent('compositionend'));assert(!dom.classList.contains('composing'),'Composition lifecycle ends'); 23 const large=Array.from({length:1000},(_,i)=>`x${i} = ${i}`).join('\n')+'\n';set(large);await frame(); 24 assert(editor.getSource()===large&&dom.querySelectorAll('.cm-line').length<1000,'Virtualization preserves complete document and trailing newline'); 25 editor.select(large.length);await frame();assert(editor.getSelection().to===large.length,'Selection uses canonical UTF-16 offsets beyond viewport'); 26 set(saved);editor.view.contentDOM.blur();editor.view.scrollDOM.scrollTop=0; 27 await pause(0);await wait(()=>['Compiled','Ready'].includes(el('status').textContent)&&!editor.isDisabled,'source restoration'); 28 // A slow engine can finish a compilation during the rendering stress check. 29 // Restore the original published session after that compilation completes. 30 if(initiallyPublished&&el('status').textContent==='Compiled'){el('restore-source').click();await status('Ready');} 31 }