fix(#5493): honor reduced motion for transparent fade
This commit is contained in:
parent
45a203b36b
commit
0c1bdce023
2 changed files with 87 additions and 6 deletions
|
|
@ -4105,7 +4105,7 @@ function attachLiveStream(activeSid, streamId, uploaded=[], options={}){
|
||||||
return typeof isTransparentStream==='function'&&isTransparentStream();
|
return typeof isTransparentStream==='function'&&isTransparentStream();
|
||||||
}
|
}
|
||||||
function _shouldUseLiveProseFade(){
|
function _shouldUseLiveProseFade(){
|
||||||
return _shouldUseStreamFade() || _shouldUseTransparentStreamFade();
|
return !_streamFadeReduceMotionEnabled() && (_shouldUseStreamFade() || _shouldUseTransparentStreamFade());
|
||||||
}
|
}
|
||||||
function _streamFadeSkipNode(node){
|
function _streamFadeSkipNode(node){
|
||||||
if(!node||node.nodeType!==1) return false;
|
if(!node||node.nodeType!==1) return false;
|
||||||
|
|
@ -4382,7 +4382,6 @@ function attachLiveStream(activeSid, streamId, uploaded=[], options={}){
|
||||||
_streamFadeDomText=String(next.text||'');
|
_streamFadeDomText=String(next.text||'');
|
||||||
return next.caughtUp;
|
return next.caughtUp;
|
||||||
}
|
}
|
||||||
_streamFadeBindCleanup(assistantBody);
|
|
||||||
if(_smdParser){
|
if(_smdParser){
|
||||||
_smdEndParser();
|
_smdEndParser();
|
||||||
assistantBody.textContent='';
|
assistantBody.textContent='';
|
||||||
|
|
@ -4397,7 +4396,7 @@ function attachLiveStream(activeSid, streamId, uploaded=[], options={}){
|
||||||
_streamFadeDomText='';
|
_streamFadeDomText='';
|
||||||
}
|
}
|
||||||
const delta=String(next.text||'').slice(_streamFadeDomText.length);
|
const delta=String(next.text||'').slice(_streamFadeDomText.length);
|
||||||
_streamFadeAppendText(assistantBody,delta);
|
if(delta) assistantBody.appendChild(document.createTextNode(delta));
|
||||||
_streamFadeDomText=String(next.text||'');
|
_streamFadeDomText=String(next.text||'');
|
||||||
return next.caughtUp;
|
return next.caughtUp;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -169,15 +169,16 @@ def test_stream_fade_uses_incremental_renderer_without_changing_default_path():
|
||||||
"_smdNewParser(assistantBody,true)",
|
"_smdNewParser(assistantBody,true)",
|
||||||
"_smdWrite(next.text,true)",
|
"_smdWrite(next.text,true)",
|
||||||
"_sanitizeSmdLinks(assistantBody)",
|
"_sanitizeSmdLinks(assistantBody)",
|
||||||
"_streamFadeBindCleanup(assistantBody)",
|
"assistantBody.appendChild(document.createTextNode(delta))",
|
||||||
"_streamFadeAppendText(assistantBody,delta)",
|
|
||||||
"_streamFadeDomText=String(next.text||'')",
|
"_streamFadeDomText=String(next.text||'')",
|
||||||
"stream-fade-active",
|
"stream-fade-active",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
assert render_block.index("_smdWrite(next.text,true)") < render_block.index(
|
assert render_block.index("_smdWrite(next.text,true)") < render_block.index(
|
||||||
"_streamFadeAppendText(assistantBody,delta)"
|
"assistantBody.appendChild(document.createTextNode(delta))"
|
||||||
)
|
)
|
||||||
|
assert "_streamFadeAppendText(assistantBody,delta)" not in render_block
|
||||||
|
assert "_streamFadeBindCleanup(assistantBody)" not in render_block
|
||||||
append_block = function_block(MESSAGES_JS, "_streamFadeAppendText")
|
append_block = function_block(MESSAGES_JS, "_streamFadeAppendText")
|
||||||
assert_contains_all(
|
assert_contains_all(
|
||||||
append_block,
|
append_block,
|
||||||
|
|
@ -276,6 +277,7 @@ def test_transparent_anchor_prose_uses_fade_renderer_when_enabled():
|
||||||
assert_contains_all(
|
assert_contains_all(
|
||||||
predicate_block,
|
predicate_block,
|
||||||
[
|
[
|
||||||
|
"!_streamFadeReduceMotionEnabled()",
|
||||||
"_shouldUseStreamFade()",
|
"_shouldUseStreamFade()",
|
||||||
"_shouldUseTransparentStreamFade()",
|
"_shouldUseTransparentStreamFade()",
|
||||||
],
|
],
|
||||||
|
|
@ -284,6 +286,86 @@ def test_transparent_anchor_prose_uses_fade_renderer_when_enabled():
|
||||||
assert "typeof isTransparentStream==='function'&&isTransparentStream()" in MESSAGES_JS
|
assert "typeof isTransparentStream==='function'&&isTransparentStream()" in MESSAGES_JS
|
||||||
|
|
||||||
|
|
||||||
|
def test_reduced_motion_disables_live_prose_fade_predicate():
|
||||||
|
script = (
|
||||||
|
"\n".join(
|
||||||
|
function_block(MESSAGES_JS, name)
|
||||||
|
for name in [
|
||||||
|
"_shouldUseStreamFade",
|
||||||
|
"_shouldUseTransparentStreamFade",
|
||||||
|
"_streamFadeReduceMotionEnabled",
|
||||||
|
"_shouldUseLiveProseFade",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
+ r"""
|
||||||
|
let _streamFadeReduceMotionMql=null;
|
||||||
|
let _streamFadeReduceMotion=false;
|
||||||
|
let _streamFadeReduceMotionOnChange=null;
|
||||||
|
let transparent=true;
|
||||||
|
let reduceMotion=true;
|
||||||
|
global.window={
|
||||||
|
_fadeTextEffect:true,
|
||||||
|
matchMedia(){
|
||||||
|
return {
|
||||||
|
get matches(){ return reduceMotion; },
|
||||||
|
addEventListener(){},
|
||||||
|
removeEventListener(){},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
function isTransparentStream(){ return transparent; }
|
||||||
|
if(_shouldUseLiveProseFade()) throw new Error('reduced motion allowed live prose fade');
|
||||||
|
_streamFadeReduceMotionMql=null;
|
||||||
|
reduceMotion=false;
|
||||||
|
window._fadeTextEffect=false;
|
||||||
|
if(!_shouldUseLiveProseFade()) throw new Error('transparent stream fade should work when motion is allowed');
|
||||||
|
_streamFadeReduceMotionMql=null;
|
||||||
|
transparent=false;
|
||||||
|
window._fadeTextEffect=true;
|
||||||
|
if(!_shouldUseLiveProseFade()) throw new Error('regular fade preference should work when motion is allowed');
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
run_node(script)
|
||||||
|
|
||||||
|
|
||||||
|
def test_transparent_stream_hidden_body_appends_plain_text_only():
|
||||||
|
script = (
|
||||||
|
function_block(MESSAGES_JS, "_renderStreamingFadeMarkdown")
|
||||||
|
+ r"""
|
||||||
|
let _streamFadeDomText='';
|
||||||
|
let _smdParser=null;
|
||||||
|
let _smdReconnect=false;
|
||||||
|
let parserEnded=false;
|
||||||
|
function _streamFadeNextText(){ return {changed:true,caughtUp:false,text:'alpha beta'}; }
|
||||||
|
function _shouldUseTransparentStreamFade(){ return true; }
|
||||||
|
function _smdEndParser(){ parserEnded=true; }
|
||||||
|
const assistantBody={
|
||||||
|
textContent:'',
|
||||||
|
innerHTML:'',
|
||||||
|
children:[],
|
||||||
|
classList:{added:[],add(name){ this.added.push(name); }},
|
||||||
|
appendChild(node){
|
||||||
|
this.children.push(node);
|
||||||
|
this.textContent += String(node.textContent || '');
|
||||||
|
return node;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
global.document={
|
||||||
|
createTextNode(text){ return {type:'text',textContent:String(text)}; },
|
||||||
|
};
|
||||||
|
const caughtUp=_renderStreamingFadeMarkdown('alpha beta');
|
||||||
|
if(caughtUp) throw new Error('expected fade playout to remain catching up');
|
||||||
|
if(assistantBody.textContent!=='alpha beta') throw new Error(`wrong hidden text: ${assistantBody.textContent}`);
|
||||||
|
if(_streamFadeDomText!=='alpha beta') throw new Error(`wrong dom text: ${_streamFadeDomText}`);
|
||||||
|
if(assistantBody.children.some(node=>node.className==='stream-fade-word is-new')){
|
||||||
|
throw new Error('hidden body received fade span');
|
||||||
|
}
|
||||||
|
if(!assistantBody.classList.added.includes('stream-fade-active')) throw new Error('missing stream fade active marker');
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
run_node(script)
|
||||||
|
|
||||||
|
|
||||||
def test_transparent_anchor_prose_receives_revealed_fade_text():
|
def test_transparent_anchor_prose_receives_revealed_fade_text():
|
||||||
render_section = slice_between(
|
render_section = slice_between(
|
||||||
MESSAGES_JS,
|
MESSAGES_JS,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue