Skip to content

Commit 90de18b

Browse files
committed
Skip unchanged tabIndex recascade
1 parent 48555d0 commit 90de18b

2 files changed

Lines changed: 37 additions & 7 deletions

File tree

‎experiments/WebScene.NativeEngine.Probe/native/webscene_v8_runtime_dom_properties.inc‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2578,7 +2578,13 @@
25782578
const auto tab_index = value->Int32Value(
25792579
info.GetIsolate()->GetCurrentContext()).FromMaybe(0);
25802580
self->record_html_attribute_feature("tabindex", "dom-property-set");
2581-
node->attributes["tabindex"] = std::to_string(tab_index);
2581+
const auto serialized = std::to_string(tab_index);
2582+
const auto previous = node->attributes.find("tabindex");
2583+
if (previous != node->attributes.end()
2584+
&& previous->second == serialized) {
2585+
return;
2586+
}
2587+
node->attributes["tabindex"] = serialized;
25822588
self->recascade_connected_subtree(*node, "style.cssText");
25832589
}
25842590

‎experiments/WebScene.NativeEngine.Probe/tests/native_v8_runtime_frame_scheduling_tests.inc‎

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1177,7 +1177,7 @@ void test_identical_selector_attribute_writes_do_not_schedule_transitions()
11771177
customElements.define('id-noop-probe', IdNoopProbe);
11781178
const style = document.createElement('style');
11791179
style.textContent = `
1180-
#code-oss-row-id[data-index="17"][aria-posinset="18"] {
1180+
#code-oss-row-id[data-index="17"][aria-posinset="18"][tabindex="0"] {
11811181
display: block;
11821182
width: 120px;
11831183
height: 24px;
@@ -1188,23 +1188,36 @@ void test_identical_selector_attribute_writes_do_not_schedule_transitions()
11881188
target.id = 'code-oss-row-id';
11891189
target.setAttribute('data-index', '17');
11901190
target.setAttribute('aria-posinset', '18');
1191+
target.tabIndex = 0;
11911192
document.body.appendChild(target);
11921193
globalThis.__idNoopTarget = target;
11931194
})()
11941195
)JS", "id-noop-setup.js");
11951196
require(
1196-
evaluate(engine, "__idNoopTarget.offsetWidth", "id-noop-ready.js") == "120",
1197+
evaluate(engine, R"JS((() => {
1198+
const normalization = document.createElement('button');
1199+
normalization.setAttribute('tabindex', '00');
1200+
normalization.tabIndex = 0;
1201+
return [
1202+
__idNoopTarget.offsetWidth,
1203+
__idNoopTarget.tabIndex,
1204+
__idNoopTarget.getAttribute('tabindex'),
1205+
normalization.getAttribute('tabindex')
1206+
];
1207+
})())JS", "id-noop-ready.js") == R"([120,0,"0","0"])",
11971208
"id no-op fixture did not complete initial layout");
11981209
acknowledge_latest_scene("id no-op setup scene could not be acknowledged");
11991210

12001211
#if defined(WEBSCENE_NATIVE_ENGINE_CERTIFICATION)
12011212
std::this_thread::sleep_for(std::chrono::milliseconds(275));
12021213
execute_and_wait_for_wrapper_retention_scene(engine,
1203-
"document.body.style.backgroundColor='rgb(1,2,3)'",
1214+
"document.body.setAttribute('data-noop-diagnostic', 'before')",
12041215
"id-noop-diagnostic-before.js");
12051216
acknowledge_latest_scene("id no-op baseline diagnostic scene could not be acknowledged");
12061217
const auto transitions_before = runtime_counter_diagnostic(
12071218
engine, "attribute-transition-schedule-requests");
1219+
const auto recascades_before = runtime_counter_diagnostic(
1220+
engine, "style-recascade-schedule-requests");
12081221
#endif
12091222

12101223
std::this_thread::sleep_for(std::chrono::milliseconds(25));
@@ -1221,18 +1234,21 @@ void test_identical_selector_attribute_writes_do_not_schedule_transitions()
12211234
target.setAttribute('id', 'code-oss-row-id');
12221235
target.setAttribute('data-index', '17');
12231236
}
1237+
target.tabIndex = 0;
12241238
}
12251239
return [
12261240
target.attributeNotifications - notificationsBefore,
12271241
target.id,
12281242
target.getAttribute('id'),
12291243
target.getAttribute('data-index'),
12301244
target.getAttribute('aria-posinset'),
1245+
target.tabIndex,
1246+
target.getAttribute('tabindex'),
12311247
target.lastAttributeChange
12321248
];
12331249
})())JS", "id-noop-connected.js");
12341250
require(
1235-
connected == R"JSON([8192,"code-oss-row-id","code-oss-row-id","17","18",["aria-posinset","18","18"]])JSON",
1251+
connected == R"JSON([8192,"code-oss-row-id","code-oss-row-id","17","18",0,"0",["aria-posinset","18","18"]])JSON",
12361252
"identical connected selector-attribute writes changed reflection or reaction semantics: "
12371253
+ connected);
12381254
std::this_thread::sleep_for(std::chrono::milliseconds(50));
@@ -1246,14 +1262,19 @@ void test_identical_selector_attribute_writes_do_not_schedule_transitions()
12461262
#if defined(WEBSCENE_NATIVE_ENGINE_CERTIFICATION)
12471263
std::this_thread::sleep_for(std::chrono::milliseconds(275));
12481264
execute_and_wait_for_wrapper_retention_scene(engine,
1249-
"document.body.style.backgroundColor='rgb(3,2,1)'",
1265+
"document.body.setAttribute('data-noop-diagnostic', 'after')",
12501266
"id-noop-diagnostic-after.js");
12511267
acknowledge_latest_scene("id no-op result diagnostic scene could not be acknowledged");
12521268
require(
12531269
runtime_counter_diagnostic(
12541270
engine, "attribute-transition-schedule-requests")
12551271
== transitions_before,
12561272
"identical selector-attribute writes entered the transition planner");
1273+
require(
1274+
runtime_counter_diagnostic(
1275+
engine, "style-recascade-schedule-requests")
1276+
== recascades_before,
1277+
"identical tabIndex writes scheduled subtree recascades");
12571278
#endif
12581279

12591280
execute_and_wait(engine,
@@ -1275,6 +1296,7 @@ void test_identical_selector_attribute_writes_do_not_schedule_transitions()
12751296
target.setAttribute('id', 'code-oss-row-id');
12761297
target.setAttribute('data-index', '17');
12771298
}
1299+
target.tabIndex = 0;
12781300
}
12791301
return [target.attributeNotifications - notificationsBefore, target.isConnected];
12801302
})())JS", "id-noop-detached.js");
@@ -1305,12 +1327,14 @@ void test_identical_selector_attribute_writes_do_not_schedule_transitions()
13051327
attribute: __idNoopTarget.getAttribute('id'),
13061328
dataIndex: __idNoopTarget.getAttribute('data-index'),
13071329
ariaPosition: __idNoopTarget.getAttribute('aria-posinset'),
1330+
tabIndex: __idNoopTarget.tabIndex,
1331+
tabIndexAttribute: __idNoopTarget.getAttribute('tabindex'),
13081332
width: __idNoopTarget.offsetWidth,
13091333
connected: __idNoopTarget.isConnected,
13101334
indexed: document.getElementById('code-oss-row-id') === __idNoopTarget,
13111335
notifications: __idNoopTarget.attributeNotifications
13121336
}))())JS", "id-noop-reattach-result.js")
1313-
== R"JSON({"reflected":"code-oss-row-id","attribute":"code-oss-row-id","dataIndex":"17","ariaPosition":"18","width":120,"connected":true,"indexed":true,"notifications":16387})JSON",
1337+
== R"JSON({"reflected":"code-oss-row-id","attribute":"code-oss-row-id","dataIndex":"17","ariaPosition":"18","tabIndex":0,"tabIndexAttribute":"0","width":120,"connected":true,"indexed":true,"notifications":16387})JSON",
13141338
"selector-attribute no-op state did not survive detach and reconnect");
13151339
webscene_engine_get_metrics(engine, &reattached);
13161340
require(

0 commit comments

Comments
 (0)