q-components
section
Includes: tests 10, 11, 12, 25, 26, 29, 30, 39, 47, 48, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 100, 103, 110, 111, 112, 113, 114, 118, 119
q-component behavior, properties, signals, inheritance, model-view components, component scoping, spritesheets, state machines, and lifecycle sequencing.
Back to test index.
10. q-component + q-property + slot
pending
Expected: Welcome | Projected content.
q-component app-card { q-property { title } div { h3 { text { ${this.component.title} } } slot { body } } } app-card { title: "Welcome" body { p { text { Projected content. } } } }
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(10, this.innerHTML);
}
}
11. q-signal declarative on<Signal> + mixed-case handler
pending
Expected: hello world
q-component signal-probe {
q-signal ping(message)
function fire() {
this.ping("hello world")
}
}
div#t11-out { text { waiting } }
signal-probe#t11-src {
onPiNg {
try {
$("#t11-out").textContent = event.detail.params.message;
var acc = document.querySelector("#acc-main");
if (acc && typeof acc.setPassing === "function") {
acc.setPassing(11, true);
} else if (acc && typeof acc.passingReported === "function") {
acc.passingReported(11, true);
}
} catch (err) {
console.warn("t11 onPiNg failed", err);
}
}
}
onReady {
try {
var acc = document.querySelector("#acc-main");
if (acc && typeof acc.setPassing === "function") {
acc.setPassing(11, false);
} else if (acc && typeof acc.passingReported === "function") {
acc.passingReported(11, false);
}
$("#t11-src").fire();
} catch (err) {
console.warn("t11 onReady failed", err);
}
}
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(11, this.innerHTML);
}
}
12. q-alias
pending
Expected: hello world
q-component mycomp { q-alias myotherprop { return "hello world"; } div { text { ${this.component.myotherprop} } } } mycomp { }
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(12, this.innerHTML);
}
}
25. extends single inheritance
pending
Expected: base-ok
q-component base-label { q-property label: "base-ok" } q-component child-label extends base-label { div { text { ${this.component.label} } } } child-label { }
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(25, this.innerHTML);
}
}
26. extends multiple inheritance
pending
Expected: A-B
q-component base-a { q-property a: "A" } q-component base-b { q-property b: "B" } q-component child-multi extends base-a extends base-b { div { text { ${this.component.a}-${this.component.b} } } } child-multi { }
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(26, this.innerHTML);
}
}
29. q-signal same-component on<Signal> handler
pending
Expected: self-ok
q-component probe29 {
q-signal probe(message)
onPrObE {
$("#t29-out").textContent = event.detail.params.message;
}
function boot() {
this.probe("self-ok")
}
}
probe29#t29-probe { }
div#t29-out { text { waiting } }
onReady {
$("#t29-probe").boot();
}
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(29, this.innerHTML);
}
}
30. q-signal multiple subscribers receive same emit
pending
Expected: multi-ok-a | multi-ok-b
q-component emitter30 {
q-signal ping(value)
function fireNow() {
this.ping("multi-ok")
}
}
emitter30#t30-em { }
div#t30-a { text { waiting-a } }
div#t30-b { text { waiting-b } }
onReady {
var em = $("#t30-em");
em.ping.connect(function(value) {
$("#t30-a").textContent = String(value) + "-a";
});
em.ping.connect(function(value) {
$("#t30-b").textContent = String(value) + "-b";
});
em.fireNow();
}
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(30, this.innerHTML);
}
}
39. q-property changed signal via .connect
pending
Expected: test has been deprecated
div { text { test has been deprecated } }
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(39, this.innerHTML);
}
}
47. q-signal forwarded through component method
pending
Expected: forward-ok
q-component source47 {
q-signal step(value)
function run() {
this.step("forward-ok")
}
}
q-component relay47 {
q-signal done(value)
function wire() {
var self = this;
$("#src47").step.connect(function(value) {
self.done(value);
});
}
}
source47#src47 { }
relay47#relay47 {
onDoNe {
$("#t47-out").textContent = event.detail.params.value;
}
}
div#t47-out { text { waiting } }
onReady {
$("#relay47").wire();
$("#src47").run();
}
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(47, this.innerHTML);
}
}
48. q-signal disconnect after first emit
pending
Expected: count=1
q-component emitter48 {
q-logger { q-signal q-property function }
q-signal tick()
function fireTwice() {
this.tick();
this.tick();
}
}
emitter48#t48-em { }
div#t48-out { text { waiting } }
onReady {
var em = $("#t48-em");
var count = 0;
var handler = function() {
count = count + 1;
$("#t48-out").textContent = "count=" + count;
em.tick.disconnect(handler);
};
em.tick.connect(handler);
em.fireTwice();
}
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(48, this.innerHTML);
}
}
50. q-signal .connect receives args
pending
Expected: payload-7
q-component emitter50 {
q-signal fired(value, count)
function fireNow() {
this.fired("payload", 7)
}
}
emitter50#t50-em { }
div#t50-out { text { waiting } }
onReady {
var em = $("#t50-em");
em.fired.connect(function(value, count) {
$("#t50-out").textContent = String(value) + "-" + String(count);
});
em.fireNow();
}
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(50, this.innerHTML);
}
}
51. q-signal .connect cross-component receiver
pending
Expected: cross-ok
q-component emitter51 {
q-logger { q-signal q-property function }
q-signal done(msg)
function run() { this.done("cross-ok"); }
}
q-component receiver51 {
q-logger { q-signal q-property function }
onReady {
$("#t51-em").done.connect(function(msg) {
$("#t51-out").textContent = msg;
});
}
}
emitter51#t51-em { }
receiver51 { }
div#t51-out { text { waiting } }
onReady {
$("#t51-em").run();
}
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(51, this.innerHTML);
}
}
52. q-signal .disconnect removes subscriber
pending
Expected: count=0|disconnect-ok
q-component emitter52 {
q-signal done(value)
function fireNow(value) { this.done(value); }
}
emitter52#t52-em { }
div#t52-out { text { waiting } }
onReady {
var em = $("#t52-em");
var count = 0;
var handler = function(value) {
count = count + 1;
$("#t52-out").textContent = "count=" + count + "|value=" + String(value);
};
em.done.connect(handler);
em.done.disconnect(handler);
em.fireNow("should-not-deliver");
window.setTimeout(function() {
if (count === 0) {
$("#t52-out").textContent = "count=0|disconnect-ok";
}
}, 40);
}
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(52, this.innerHTML);
}
}
53. q-property changed: declarative + manual subscription (multi-change)
pending
Expected: prop53-ok
q-component prop53 {
q-logger { q-signal q-property function }
q-property count: 0
function appendValue(nodeId, value) {
var node = $("#" + nodeId);
var current = String(node.textContent || "");
if (current.trim() === "waiting") {
current = "";
}
node.textContent = current ? (current + "," + String(value)) : String(value);
}
onCoUnTcHaNgEd {
this.appendValue("t53-decl", event.detail.params.value);
}
function run() {
var self = this;
this.addEventListener("countChanged", function(event) {
self.appendValue("t53-manual", event.detail.params.value);
});
this.countChanged.connect(function(value) {
self.appendValue("t53-connect", value);
});
this.count = 1;
this.count = 2;
this.count = 3;
window.setTimeout(function() {
var decl = $("#t53-decl").textContent;
var manual = $("#t53-manual").textContent;
var connected = $("#t53-connect").textContent;
if (decl === "1,2,3" && manual === "1,2,3" && connected === "1,2,3") {
$("#t53-status").textContent = "prop53-ok";
} else {
$("#t53-status").textContent = "prop53-fail|" + decl + "|" + manual + "|" + connected;
}
}, 80);
}
}
prop53#t53-probe { }
div#t53-decl { text { waiting } }
div#t53-manual { text { waiting } }
div#t53-connect { text { waiting } }
div#t53-status { text { waiting } }
onReady {
$("#t53-probe").run();
}
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(53, this.innerHTML);
}
}
54. lowercase on<property>changed + q-timer property mutation
pending
Expected: prop54-ok
q-component mycomp54 {
q-logger { q-signal q-property function }
q-property myprop
onmypropchanged {
this.querySelector("div").innerHTML = String(this.component.myprop);
}
div { text { waiting } }
}
mycomp54#mycomp54 { }
q-timer mytimer54 {
repeat: false
interval: 500
ontimeout {
document.querySelector("#mycomp54").myprop = "prop54-ok";
}
running: true
}
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(54, this.innerHTML);
}
}
55. q-logger q-property (manual button)
pending
Expected: hello world
q-component propertyTest55 {
q-property myprop
q-logger { q-property }
button#t55-run {
type: "button"
onclick {
var host = this.closest("propertyTest55");
host.myprop = "hello world";
host.querySelector("#t55-out").textContent = host.myprop;
host.querySelector("#t55-done").textContent = "1";
}
text { test property log }
}
div#t55-out { text { waiting } }
div#t55-done { text { 0 } }
}
propertyTest55 { }
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(55, this.innerHTML);
}
}
56. q-logger q-signal (manual button)
pending
Expected: signal-ok
q-component signalTest56 {
q-signal ping(value)
q-logger { q-signal }
onPing {
this.querySelector("#t56-out").textContent = event.detail.params.value;
this.querySelector("#t56-done").textContent = "1";
}
button#t56-run {
type: "button"
onclick {
this.closest("signalTest56").ping("signal-ok");
}
text { test signal log }
}
div#t56-out { text { waiting } }
div#t56-done { text { 0 } }
}
signalTest56 { }
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(56, this.innerHTML);
}
}
57. q-logger q-component (manual button)
pending
Expected: component-ok
q-component componentTest57 {
q-property status: "waiting"
q-logger { q-component }
button#t57-run {
type: "button"
onclick {
var host = this.closest("componentTest57");
host.status = "component-ok";
host.querySelector("#t57-out").textContent = host.status;
host.querySelector("#t57-done").textContent = "1";
}
text { test component log }
}
div#t57-out { text { waiting } }
div#t57-done { text { 0 } }
}
componentTest57 { }
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(57, this.innerHTML);
}
}
58. q-logger function (manual button)
pending
Expected: 1
q-component functionTest58 {
q-property count: 0
q-logger { function }
function bump() { this.count = Number(this.count || 0) + 1; return this.count; }
button#t58-run {
type: "button"
onclick {
var host = this.closest("functionTest58");
host.querySelector("#t58-out").textContent = String(host.bump());
host.querySelector("#t58-done").textContent = "1";
}
text { test function log }
}
div#t58-out { text { waiting } }
div#t58-done { text { 0 } }
}
functionTest58 { }
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(58, this.innerHTML);
}
}
59. q-logger slot (manual button)
pending
Expected: slot-ok
q-component slotTest59 {
q-logger { slot }
slot { body }
div#t59-projected { slot { body } }
button#t59-run {
type: "button"
onclick {
var host = this.closest("slotTest59");
host.querySelector("#t59-out").textContent = host.querySelector("#t59-projected").textContent.trim();
host.querySelector("#t59-done").textContent = "1";
}
text { test slot log }
}
div#t59-out { text { waiting } }
div#t59-done { text { 0 } }
}
slotTest59 {
body { slot-ok }
}
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(59, this.innerHTML);
}
}
60. q-logger model (manual button)
pending
Expected: 4
q-model t60-model { q-array { 1, 2, 3 } }
div#t60-scope { q-logger { model } }
button#t60-run {
type: "button"
onclick {
var host = this.closest("q-html");
var model = host["t60-model"];
model.add(4);
host.querySelector("#t60-out").textContent = String(model.count());
host.querySelector("#t60-done").textContent = "1";
}
text { test model log }
}
div#t60-out { text { waiting } }
div#t60-done { text { 0 } }
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(60, this.innerHTML);
}
}
61. q-logger instantiation (manual button)
pending
Expected: instantiation-ok
q-component instTest61 {
q-property status: "waiting"
q-logger { instantiation }
button#t61-run {
type: "button"
onclick {
var host = this.closest("instTest61");
host.status = "instantiation-ok";
host.querySelector("#t61-out").textContent = host.status;
host.querySelector("#t61-done").textContent = "1";
}
text { test instantiation log }
}
div#t61-out { text { waiting } }
div#t61-done { text { 0 } }
}
instTest61 { }
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(61, this.innerHTML);
}
}
62. q-logger multi categories (manual button)
pending
Expected: multi-ok-1
q-component multiTest62 {
q-property count: 0
q-signal ping(value)
q-logger { q-property q-signal function }
function bump() { this.count = Number(this.count || 0) + 1; return this.count; }
onPing {
this.querySelector("#t62-out").textContent = event.detail.params.value + "-" + String(this.count);
this.querySelector("#t62-done").textContent = "1";
}
button#t62-run {
type: "button"
onclick {
var host = this.closest("multiTest62");
host.bump();
host.ping("multi-ok");
}
text { test multi logger }
}
div#t62-out { text { waiting } }
div#t62-done { text { 0 } }
}
multiTest62 { }
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(62, this.innerHTML);
}
}
63. q-logger multi-scope override (manual button)
pending
Expected: a=1|b=1
q-component scopeTest63 {
q-property count: 0
q-logger { q-property }
div.out { text { ${this.component.count} } }
}
scopeTest63#t63-a { }
scopeTest63#t63-b { q-logger { q-signal } }
button#t63-run {
type: "button"
onclick {
var host = this.closest("q-html");
var a = host.querySelector("#t63-a");
var b = host.querySelector("#t63-b");
a.count = Number(a.count || 0) + 1;
b.count = Number(b.count || 0) + 1;
host.querySelector("#t63-out").textContent = "a=" + String(a.count) + "|b=" + String(b.count);
host.querySelector("#t63-done").textContent = "1";
}
text { test scope override }
}
div#t63-out { text { waiting } }
div#t63-done { text { 0 } }
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(63, this.innerHTML);
}
}
64. qdom().qmap() keyword extraction
pending
Expected: q-property | foo | q-signal | done
q-component probe64 {
q-logger { q-signal q-property }
q-property foo: "bar"
q-signal done(value)
slot { body }
div { text { probe64 } }
}
probe64#t64-inst { body { div { text { projected } } } }
div#t64-out { text { waiting } }
onReady {
var defNode = this.qdom().find("probe64");
var mapped = defNode ? defNode.qmap(["q-property", "q-signal", "slot"], false) : {};
$("#t64-out").textContent = JSON.stringify(mapped);
}
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(64, this.innerHTML);
}
}
65. empty q-map populate + q-property change propagation
pending
Expected: map65-ok|
q-component mapPump65 {
q-logger { q-signal q-property }
q-property payload: q-map { }
q-property status: "waiting"
q-signal payloadUpdated(value)
onstatusChanged {
this.querySelector("#t65-status").textContent = String(this.status);
}
onpayloadChanged {
var data = this.payload || {};
this.status = "map65-ok|" + String(Object.keys(data).length);
this.payloadUpdated(this.status);
}
onpayloadUpdated {
this.querySelector("#t65-signal").textContent = String(event.detail.params.value || "");
}
function run() {
var existing = this.payload || {};
existing.name = "alpha";
existing.count = 7;
this.payload = Object.assign({}, existing);
}
div#t65-status { text { waiting } }
div#t65-signal { text { waiting } }
}
mapPump65#t65-host { }
onReady {
$("#t65-host").run();
}
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(65, this.innerHTML);
}
}
66. q-tree-view setModel from instance qdom().qmap()
pending
Expected: q-property | count | q-signal | done | slot
q-import { dist/q-components/q-tree-view.qhtml?v=tree-css-28 }
q-component comp66 {
q-property count: 1
q-signal done(value)
slot { body }
div { text { comp66 } }
}
comp66#t66-comp {
body { span { text { projected66 } } }
}
q-tree-view#t66-tree { model: q-map { } }
div#t66-out { text { waiting } }
onReady {
var source = $("#t66-comp").qdom();
var mapped = source.qmap(["q-property", "q-signal", "slot"], true);
$("#t66-tree").setModel(mapped);
$("#t66-out").textContent = JSON.stringify(mapped);
}
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(66, this.innerHTML);
}
}
68. q-model-view using model { q-array { ... } } + as alias
pending
Expected: model-array-as a | model-array-as b | model-array-as c
q-model-view {
model { q-array { "a", "b", "c" } }
as { item }
div { text { model-array-as ${item} } }
}
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(68, this.innerHTML);
}
}
69. q-model-view using slot alias keyword
pending
Expected: model-slot-alias 7 | model-slot-alias 8
q-model-view {
q-model { q-array { 7, 8 } }
slot { row }
div { text { model-slot-alias ${row} } }
}
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(69, this.innerHTML);
}
}
70. q-model named from q-map + q-model-view model reference
pending
Expected: model-map-ref alpha
q-model my-model70 {
q-map { first: "alpha", second: "beta" }
}
q-model-view {
model { my-model70 }
as { item }
div { text { model-map-ref ${item.first || item.second || item} } }
}
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(70, this.innerHTML);
}
}
71. q-model-view with q-model q-script array source
pending
Expected: model-script-source 11 | model-script-source 12 | model-script-source 13
q-model-view {
q-model {
q-script { return [11, 12, 13] }
}
as { item }
div { text { model-script-source ${item} } }
}
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(71, this.innerHTML);
}
}
72. q-model-view inheritance: component extends q-model-view
pending
Expected: base72 x | base72 y | child72 x | child72 y | slot72
q-component base-model-view72 extends q-model-view {
q-model { q-array { "x", "y" } }
as { item }
div.base72 {
text { base72 ${this.component.item} }
slot { extra }
}
}
q-component child-model-view72 extends base-model-view72 {
div.child72 {
text { child72 ${this.component.item} }
}
}
child-model-view72#t72-inst {
extra { span { text { slot72 } } }
}
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(72, this.innerHTML);
}
}
73. deep extends precedence: lowest-level overrides ancestors
pending
Expected: ancestor73-leaf-leaf | leaf73-leaf-leaf
q-component ancestor73 {
q-property label: "ancestor"
function who() { return "ancestor" }
div { text { ancestor73-${this.component.label}-${this.component.who()} } }
}
q-component middle73 extends ancestor73 {
q-property label: "middle"
function who() { return "middle" }
}
q-component leaf73 extends middle73 {
q-property label: "leaf"
function who() { return "leaf" }
div { text { leaf73-${this.component.label}-${this.component.who()} } }
}
leaf73 { }
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(73, this.innerHTML);
}
}
74. deep q-model-view inheritance chain
pending
Expected: root74-r1 | mid74-r1 | leaf74-r1 | root74-r2 | mid74-r2 | leaf74-r2
q-component root74 extends q-model-view {
model { q-array { "r1", "r2" } }
as { row }
div { text { root74-${this.component.row} } }
}
q-component mid74 extends root74 {
as { row2 }
div { text { mid74-${this.component.row2 || this.component.row} } }
}
q-component leaf74 extends mid74 {
div { text { leaf74-${this.component.row2 || this.component.row} } }
}
leaf74 { }
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(74, this.innerHTML);
}
}
75. double extends: component extends component extends q-model-view
pending
Expected: mycomp1-one | mycomp2-one | mycomp1-two | mycomp2-two
q-component mycomp1 extends q-model-view {
model { q-array { "one", "two" } }
as { item }
div { text { mycomp1-${this.component.item} } }
}
q-component mycomp2 extends mycomp1 extends q-model-view {
div { text { mycomp2-${this.component.item} } }
}
mycomp2 { }
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(75, this.innerHTML);
}
}
76. q-model mutators update q-model-view
pending
Expected: Z0|a|B2|c | Z0 | a | B2 | c
q-model t76model {
q-array { "a", "b" }
}
q-model-view {
q-model { t76model }
as { item }
div.t76-row { text { ${item} } }
}
div#t76-status { text { waiting } }
onReady {
var host = this;
host.t76model.push("c");
host.t76model.push_front("z");
host.t76model.set(2, "B2");
host.t76model.replace(0, "Z0");
document.querySelector("#t76-status").textContent = host.t76model.values().join("|");
}
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(76, this.innerHTML);
}
}
77. q-model modelChanged.connect emits per mutation
pending
Expected: remove|3
q-model t77model {
q-map { one: "1" }
}
div#t77-log { text { waiting } }
onReady {
var host = this;
var model = host.t77model;
var hits = 0;
model.modelChanged.connect(function(evt) {
hits = hits + 1;
document.querySelector("#t77-log").textContent = String(evt.op) + "|" + String(hits);
});
model.set("one", "11");
model.set("two", "22");
model.remove("one");
}
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(77, this.innerHTML);
}
}
78. q-model subscribe keeps legacy event types
pending
Expected: add,update,remove
q-model t78model {
q-array { 1 }
}
div#t78-log { text { waiting } }
onReady {
var host = this;
var model = host.t78model;
var seen = [];
model.subscribe(function(evt) {
seen.push(String(evt.type));
document.querySelector("#t78-log").textContent = seen.join(",");
});
model.push(2);
model.replace(0, 10);
model.remove(1);
}
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(78, this.innerHTML);
}
}
100. typed instance alias is available in script scope
pending
Expected: hello-world-100
q-component source100 {
q-property value: "hello-world-100"
}
source100 myinstance100 { }
q-component target100 {
q-property output: "waiting"
onReady {
this.component.output = ${myinstance100.value};
}
div#t100-out { text { ${this.component.output} } }
}
target100 { }
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(100, this.innerHTML);
}
}
103. q-estore product + product-grid smoke test
pending
Expected: NL-100 | Night Lamp | DC-220 | Desk Clock
q-import { dist/q-components/q-estore.qhtml }
q-estore#store103 {
products: q-array {
q-map {
SKU: "NL-100"
name: "Night Lamp"
description: "Warm bedside glow"
price: "39.99"
},
q-map {
SKU: "DC-220"
name: "Desk Clock"
description: "Minimal analog clock"
price: "24.50"
}
}
}
onReady {
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(103, this.innerHTML);
}
}
110. typed alias visibility from deep sibling descendant
pending
Expected: nested-call-110 | id="t110-btn"
q-component rootRef110 {
q-property state: "waiting"
function mark(value) {
this.component.state = String(value == null ? "" : value);
}
}
rootRef110 rootAlias110 { }
q-component deepLeaf110 {
button#t110-btn {
type: "button"
onclick { rootAlias110.mark("click-call-110"); }
text { run nested alias call }
}
div#t110-state { text { ${rootAlias110.state} } }
onReady {
var stateNode = this.querySelector("#t110-state");
try {
rootAlias110.mark("nested-call-110");
if (stateNode) {
stateNode.textContent = String(rootAlias110.state);
}
} catch (err) {
if (stateNode) {
stateNode.textContent = "nested-call-110-miss";
}
}
}
}
q-component mid110 {
deepLeaf110 leaf110 { }
}
mid110 midInst110 { }
111. component type alias resolves inside child definition scope
pending
Expected: owner-alias-111
q-component child111 {
onReady {
var out = document.querySelector("#t111-out");
if (out) {
out.textContent = String(myowner111.myprop);
}
}
}
q-component myowner111 {
q-property myprop: "owner-alias-111"
child111 {
}
}
myowner111 myinst111 { }
div#t111-out { text { waiting } }
onReady {
var acc = document.querySelector("#acc-main");
setTimeout(function() {
var out = document.querySelector("#t111-out");
var value = out ? String(out.textContent || "") : "";
if (acc && typeof acc.resultReported === "function") {
acc.resultReported(111, value);
}
}, 50);
}
112. owner-chain dot walk resolves enclosing same-type owner
pending
Expected: root-112
q-component ownerProbe112 {
onReady {
var out = document.querySelector("#t112-out");
if (out) {
out.textContent = String(myowner112.myowner112.myprop);
}
}
}
q-component myowner112 {
q-property myprop: ""
slot { body }
}
myowner112 ownerRoot112 {
myprop: "root-112"
body {
myowner112 ownerInner112 {
myprop: "inner-112"
body {
ownerProbe112 { }
}
}
}
}
div#t112-out { text { waiting } }
onReady {
var acc = document.querySelector("#acc-main");
setTimeout(function() {
var out = document.querySelector("#t112-out");
var value = out ? String(out.textContent || "") : "";
if (acc && typeof acc.resultReported === "function") {
acc.resultReported(112, value);
}
}, 60);
}
113. q-spritesheet declarative init from assets
pending
Expected: cols=18|rows=1|count=18|frame=
q-import { dist/q-components/q-spritesheet.qhtml }
q-spritesheet sprite113 {
id: "t113-sprite"
source: "tools/assets/test-ss.png"
frameCount: 18
frameStart: 0
frameStop: 17
frameDuration: 90
frameWidth: 0
frameHeight: 0
currentFrame: 0
running: true
repeat: true
interpolate: false
onframechanged(frameIndex) {
var out = document.querySelector("#host-t113 #t113-out");
if (out) {
out.textContent = "cols=" + String(this.component.columns) + "|rows=" + String(this.component.rows) + "|count=" + String(this.component.frameCount) + "|frame=" + String(frameIndex);
}
}
}
div#t113-out { text { waiting } }
div#t113-controls {
button#t113-start {
type: "button"
text { Start }
onclick { sprite113.start(); }
}
button#t113-stop {
type: "button"
text { Stop }
onclick { sprite113.stop(); }
}
}
onready {
var host = this;
setTimeout(function() {
var acc = document.querySelector("#acc-main");
var out = host.querySelector("#t113-out");
if (acc && typeof acc.resultReported === "function") {
acc.resultReported(113, out ? String(out.textContent || "") : "");
}
}, 900);
}
114. parameterized on-signal and on-propertychanged handlers
pending
Expected: signal=alpha-beta | prop=42
q-component probe114 {
q-signal emitPair(left, right)
q-property numberVal: 0
q-property signalValue: "waiting"
q-property propValue: "waiting"
onemitPair(a, b) {
this.component.signalValue = String(a) + "-" + String(b);
this.component.numberVal = 42;
var actual = "signal=" + String(this.component.signalValue) + " | prop=" + String(this.component.propValue);
var out = document.querySelector("#host-t114 #t114-out");
if (out) {
out.innerHTML = actual;
}
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(114, actual);
}
}
onnumberValchanged(v) {
this.component.propValue = String(v);
var actual = "signal=" + String(this.component.signalValue) + " | prop=" + String(this.component.propValue);
var out = document.querySelector("#host-t114 #t114-out");
if (out) {
out.innerHTML = actual;
}
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(114, actual);
}
}
onReady {
setTimeout(function() {
this.component.emitPair("alpha", "beta");
}.bind(this), 0);
}
}
probe114 testProbe114 { }
div#t114-out {
text { signal=${testProbe114.signalValue} | prop=${testProbe114.propValue} }
}
onReady {
var acc = document.querySelector("#acc-main");
var host = this;
setTimeout(function() {
var out = host.querySelector("#t114-out");
var actual = out ? String(out.textContent || "").trim() : "";
if (acc) {
acc.report(114, true, actual);
}
}, 320);
}
118. on* then-chain sequencing (lifecycle + signal)
pending
Expected: lifecycle-then-ok
q-component mycomp118 {
onready {
/* nothing */
} then {
var host = document.querySelector("#host-t118");
var out = host ? host.querySelector("#t118-out") : null;
var actual = "lifecycle-then-ok";
if (out) {
out.textContent = actual;
}
var acc = document.querySelector("#acc-main");
if (acc) {
acc.resultReported(118, actual);
acc.passingReported(118, true);
}
}
}
mycomp118 { }
div#t118-out { text { waiting } }
119. q-state-machine buttons + q-connect statechanged
pending
Expected: activated state2 | statechanged=state2 | component=1 | method=method-ok | signal=1
q-component q-a {
q-property lastState: "waiting"
function setPassing(val) {
this.component.lastState = String(val == null ? "" : val);
var out = document.querySelector("#host-t119 #t119-signal");
if (out) {
out.textContent = "statechanged=" + this.component.lastState;
}
var acc = document.querySelector("#acc-main");
if (acc && typeof acc.passingReported === "function") {
acc.passingReported(119, this.component.lastState === "state2");
}
setTimeout(function() {
var host = document.querySelector("#host-t119");
var machine = host ? host.querySelector("q-state-machine") : null;
if (machine && typeof machine.markCustom === "function") {
machine.markCustom("method-ok");
}
var stateText = host && host.querySelector("#t119-state") ? String(host.querySelector("#t119-state").textContent || "").trim() : "";
var signalText = host && host.querySelector("#t119-signal") ? String(host.querySelector("#t119-signal").textContent || "").trim() : "";
var componentText = "component=" + (machine && machine.getAttribute("qhtml-component-instance") === "1" && typeof machine.statechanged === "function" ? "1" : "0");
var methodText = "method=" + (machine && machine.machineMarker ? String(machine.machineMarker) : "missing");
var declaredSignalText = "signal=" + (machine && typeof machine.customPing === "function" ? "1" : "0");
var actual = stateText + " | " + signalText + " | " + componentText + " | " + methodText + " | " + declaredSignalText;
var meta = host ? host.querySelector("#t119-meta") : null;
if (meta) {
meta.textContent = componentText + " | " + methodText + " | " + declaredSignalText;
}
var acc2 = document.querySelector("#acc-main");
if (acc2 && typeof acc2.outcomeReported === "function") {
acc2.outcomeReported(119, actual.indexOf("activated state2") >= 0 && actual.indexOf("statechanged=state2") >= 0 && actual.indexOf("component=1") >= 0 && actual.indexOf("method=method-ok") >= 0 && actual.indexOf("signal=1") >= 0, actual);
}
}, 40);
}
}
q-state-machine mymachine {
q-property machineMarker: "unset"
q-signal customPing(value)
function markCustom(value) {
this.component.machineMarker = String(value == null ? "" : value);
}
state1 {
div#t119-state.state-one {
style { padding: 10px; border: 2px solid #2563eb; background: #dbeafe; }
h3 { text { hello world } }
}
}
state2 {
div#t119-state.state-two {
style { padding: 10px; border: 2px solid #16a34a; background: #dcfce7; }
h4 { text { activated state2 } }
}
}
}
q-a othercomponent { }
q-connect { mymachine.statechanged othercomponent.setPassing }
button#t119-state1 {
type: "button"
onclick { mymachine.state = "state1"; }
text { toggle state1 }
}
button#t119-state2 {
type: "button"
onclick { mymachine.state = "state2"; }
text { toggle state2 }
}
div#t119-signal { text { statechanged=waiting } }
div#t119-meta { text { component=0 | method=missing | signal=0 } }
onReady {
var host = this;
if (mymachine && typeof mymachine.markCustom === "function") {
mymachine.markCustom("method-ok");
}
setTimeout(function() {
var btn = host.querySelector("#t119-state2");
if (btn) {
btn.click();
}
}, 40);
setTimeout(function() {
var machine = host.querySelector("q-state-machine");
if (machine && typeof machine.markCustom === "function") {
machine.markCustom("method-ok");
}
}, 140);
setTimeout(function() {
var acc = document.querySelector("#acc-main");
var stateText = host.querySelector("#t119-state") ? String(host.querySelector("#t119-state").textContent || "").trim() : "";
var signalText = host.querySelector("#t119-signal") ? String(host.querySelector("#t119-signal").textContent || "").trim() : "";
var machine = host.querySelector("q-state-machine");
var componentText = "component=" + (machine && machine.getAttribute("qhtml-component-instance") === "1" && typeof machine.statechanged === "function" ? "1" : "0");
var methodText = "method=" + (machine && machine.machineMarker ? String(machine.machineMarker) : "missing");
var declaredSignalText = "signal=" + (machine && typeof machine.customPing === "function" ? "1" : "0");
var actual = stateText + " | " + signalText + " | " + componentText + " | " + methodText + " | " + declaredSignalText;
if (acc && typeof acc.outcomeReported === "function") {
acc.outcomeReported(119, actual.indexOf("activated state2") >= 0 && actual.indexOf("statechanged=state2") >= 0 && actual.indexOf("component=1") >= 0 && actual.indexOf("method=method-ok") >= 0 && actual.indexOf("signal=1") >= 0, actual);
} else if (acc && typeof acc.resultReported === "function") {
acc.resultReported(119, actual);
}
}, 320);
}
122. q-tech-panel paints direct child divs
pending
Expected: hello world | borderWidth=5px | topLeft=12px | background=paint | mask=paint
q-import { dist/q-components/q-tech-panel.qhtml }
q-tech-panel {
borderWidth: "5px"
borderColor: "#67e8f9"
shadowColor: "#22c55e"
topLeft: "12px"
topDent: "2vh"
topDentLength: "18%"
patternSize: "16px"
q-style divstyle {
width: 40vw
minWidth: 220px
height: 20vh
minHeight: 80px
padding: 18px
color: #e0f2fe
fontWeight: 700
}
q-theme mytheme {
div { divstyle }
}
mytheme {
div#t122-panel { text { hello world } }
}
}
div#t122-out { text { waiting } }
onReady {
var host = this;
setTimeout(function() {
var panel = host.querySelector("#t122-panel");
var out = host.querySelector("#t122-out");
var acc = document.querySelector("#acc-main");
var support = typeof CSS !== "undefined" && CSS && CSS.paintWorklet;
var text = panel ? String(panel.textContent || "").trim() : "";
var borderWidth = panel && panel.style ? String(panel.style.getPropertyValue("--borderWidth") || "").trim() : "";
var topLeft = panel && panel.style ? String(panel.style.getPropertyValue("--topLeft") || "").trim() : "";
var bg = panel && panel.style ? String(panel.style.backgroundImage || "") : "";
var mask = panel && panel.style ? String(panel.style.maskImage || panel.style.webkitMaskImage || "") : "";
var backgroundStatus = support ? (bg.indexOf("paint(") >= 0 ? "paint" : "missing") : "unsupported";
var maskStatus = support ? (mask.indexOf("paint(") >= 0 ? "paint" : "missing") : "unsupported";
var actual = text + " | borderWidth=" + borderWidth + " | topLeft=" + topLeft + " | background=" + backgroundStatus + " | mask=" + maskStatus;
var ok = text === "hello world" && borderWidth === "5px" && topLeft === "12px" && (!support || (backgroundStatus === "paint" && maskStatus === "paint"));
if (out) {
out.textContent = actual;
}
if (acc && typeof acc.outcomeReported === "function") {
acc.outcomeReported(122, ok, actual);
}
}, 650);
}
124. q-layout nested inside q-row and q-col
pending
Expected: root-layout | row-nested-layout | col-nested-layout | level-3-layout
div#t124-stage {
style { display: block; padding: 10px; border: 1px solid #cbd5e1; background: #f8fafc; }
q-layout#t124-root {
style { display: block; padding: 10px; border: 2px solid #1d4ed8; background: #dbeafe; margin-bottom: 8px; }
div { text { root-layout } }
q-row#t124-row1 {
style { display: block; padding: 8px; border: 2px solid #0f766e; background: #ccfbf1; margin-top: 8px; }
q-col#t124-col1 {
style { display: block; padding: 8px; border: 2px solid #7c3aed; background: #ede9fe; margin-top: 8px; }
q-layout#t124-nested-in-col {
style { display: block; padding: 8px; border: 2px dashed #9333ea; background: #f5f3ff; margin-top: 8px; }
div { text { col-nested-layout } }
q-row {
style { display: block; padding: 8px; border: 2px solid #be185d; background: #fce7f3; margin-top: 8px; }
q-col {
style { display: block; padding: 8px; border: 2px solid #b45309; background: #ffedd5; margin-top: 8px; }
q-layout#t124-level3 {
style { display: block; padding: 8px; border: 2px solid #374151; background: #f3f4f6; }
div { text { level-3-layout } }
}
}
}
}
}
q-layout#t124-nested-in-row {
style { display: block; padding: 8px; border: 2px dashed #065f46; background: #ecfdf5; margin-top: 8px; }
div { text { row-nested-layout } }
}
}
}
div#t124-out { text { waiting } }
}
onReady {
var host = this;
setTimeout(function() {
var acc = document.querySelector("#acc-main");
var root = host.querySelector("#t124-root");
var inRow = host.querySelector("#t124-nested-in-row");
var inCol = host.querySelector("#t124-nested-in-col");
var level3 = host.querySelector("#t124-level3");
var actual = [
root ? "root-layout" : "root-missing",
inRow ? "row-nested-layout" : "row-missing",
inCol ? "col-nested-layout" : "col-missing",
level3 ? "level-3-layout" : "level3-missing"
].join(" | ");
var out = host.querySelector("#t124-out");
if (out) {
out.textContent = actual;
}
if (acc && typeof acc.outcomeReported === "function") {
acc.outcomeReported(124, actual.indexOf("missing") < 0, actual);
} else if (acc && typeof acc.resultReported === "function") {
acc.resultReported(124, actual);
}
}, 80);
}
125. q-layout slot projection accepts injected q-row/q-col
pending
Expected: slot-row-a | slot-row-b | slot-context
q-component t125-value {
q-property label: "unset"
span.t125-value {
text { ${this.component.label} }
}
}
q-component t125-layout-shell {
q-layout#t125-slotted-layout {
width: "100%"
gap: "6px"
style { padding: 8px; border: 2px solid #2563eb; background: #eff6ff; }
slot { layoutRows }
}
}
t125-value t125source { label: "slot-context" }
t125-layout-shell t125shell {
layoutRows {
q-row#t125-slot-row-a {
height: "auto"
q-col {
width: "auto"
div { text { slot-row-a } }
}
}
q-row#t125-slot-row-b {
height: "auto"
q-col {
width: "auto"
div { text { slot-row-b } }
t125-value t125child { label: t125source.label }
}
}
}
}
div#t125-out { text { waiting } }
onReady {
var host = this;
setTimeout(function() {
var layout = host.querySelector("#t125-slotted-layout");
var rowA = host.querySelector("#t125-slot-row-a");
var rowB = host.querySelector("#t125-slot-row-b");
var child = host.querySelector(".t125-value");
var actual = [
rowA ? "slot-row-a" : "slot-row-a-missing",
rowB ? "slot-row-b" : "slot-row-b-missing",
child ? String(child.textContent || "").trim() : "slot-context-missing"
].join(" | ");
var display = layout ? getComputedStyle(layout).display : "";
var out = host.querySelector("#t125-out");
var acc = document.querySelector("#acc-main");
if (out) { out.textContent = actual + " | display=" + display; }
if (acc && typeof acc.outcomeReported === "function") {
acc.outcomeReported(125, actual === "slot-row-a | slot-row-b | slot-context" && display === "grid", actual);
}
}, 120);
}
126. q-layout context pass-through across nested layouts
pending
Expected: inst3=123 | inst4=123 | inst5=123
q-component t126-comp {
q-property blah: "unset"
div.t126-comp-out {
text { ${this.component.blah} }
slot { fun }
}
}
t126-comp inst1#t126-inst1 { blah: "abc" }
q-layout#t126-layout {
gap: "8px"
style { padding: 8px; border: 2px solid #0f766e; background: #ecfdf5; }
q-row {
q-col {
t126-comp inst2#t126-inst2 { blah: "123" }
}
}
q-row {
q-col {
q-layout#t126-nested {
q-row {
q-col {
t126-comp inst3#t126-inst3 {
blah: inst2.blah
fun { span { text { nested-slot } } }
}
}
}
}
}
}
}
t126-comp inst4#t126-inst4 {
blah: inst3.blah
fun {
q-layout#t126-slot-layout {
q-row {
q-col {
t126-comp inst5#t126-inst5 { blah: inst2.blah }
}
}
}
}
}
div#t126-out { text { waiting } }
onReady {
var host = this;
setTimeout(function() {
var i3 = host.querySelector("#t126-inst3");
var i4 = host.querySelector("#t126-inst4");
var i5 = host.querySelector("#t126-inst5");
var actual = [
"inst3=" + (i3 ? String(i3.blah) : "missing"),
"inst4=" + (i4 ? String(i4.blah) : "missing"),
"inst5=" + (i5 ? String(i5.blah) : "missing")
].join(" | ");
var out = host.querySelector("#t126-out");
var acc = document.querySelector("#acc-main");
if (out) { out.textContent = actual; }
if (acc && typeof acc.outcomeReported === "function") {
acc.outcomeReported(126, actual === "inst3=123 | inst4=123 | inst5=123", actual);
}
}, 120);
}
127. q-layout buttons add rows and columns around a container
pending
Expected: top-row | bottom-row | left-col | right-col
div#t127-controls {
style { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
button#t127-add-top {
onclick {
var layout = document.querySelector("#t127-layout");
var row = layout.addRow(0, { height: "auto" });
row.id = "t127-top-row";
row.style.padding = "6px";
row.style.background = "#dbeafe";
row.style.border = "1px solid #60a5fa";
row.textContent = "top-row";
}
text { Add top row }
}
button#t127-add-bottom {
onclick {
var layout = document.querySelector("#t127-layout");
var row = layout.addRow(Infinity, { height: "auto" });
row.id = "t127-bottom-row";
row.style.padding = "6px";
row.style.background = "#e0f2fe";
row.style.border = "1px solid #38bdf8";
row.textContent = "bottom-row";
}
text { Add bottom row }
}
button#t127-add-left {
onclick {
var row = document.querySelector("#t127-main-row");
var col = row.addCol(0, { width: "90px" });
col.id = "t127-left-col";
col.style.padding = "6px";
col.style.background = "#dcfce7";
col.style.border = "1px solid #22c55e";
col.textContent = "left-col";
}
text { Add left col }
}
button#t127-add-right {
onclick {
var row = document.querySelector("#t127-main-row");
var col = row.addCol(Infinity, { width: "90px" });
col.id = "t127-right-col";
col.style.padding = "6px";
col.style.background = "#fef3c7";
col.style.border = "1px solid #f59e0b";
col.textContent = "right-col";
}
text { Add right col }
}
}
q-layout#t127-layout {
width: "100%"
gap: "8px"
style { padding: 10px; border: 2px solid #334155; background: #f8fafc; }
q-row#t127-main-row {
height: "auto"
q-col#t127-center-col {
width: "1fr"
div#t127-center {
style { padding: 12px; background: #ffffff; border: 1px solid #cbd5e1; text-align: center; }
text { center }
}
}
}
}
div#t127-out { text { waiting } }
onReady {
var host = this;
setTimeout(function() {
host.querySelector("#t127-add-top").click();
host.querySelector("#t127-add-bottom").click();
host.querySelector("#t127-add-left").click();
host.querySelector("#t127-add-right").click();
setTimeout(function() {
var tokens = [
host.querySelector("#t127-top-row") ? "top-row" : "top-row-missing",
host.querySelector("#t127-bottom-row") ? "bottom-row" : "bottom-row-missing",
host.querySelector("#t127-left-col") ? "left-col" : "left-col-missing",
host.querySelector("#t127-right-col") ? "right-col" : "right-col-missing"
];
var actual = tokens.join(" | ");
var out = host.querySelector("#t127-out");
var acc = document.querySelector("#acc-main");
if (out) { out.textContent = actual; }
if (acc && typeof acc.outcomeReported === "function") {
acc.outcomeReported(127, actual === "top-row | bottom-row | left-col | right-col", actual);
}
}, 80);
}, 120);
}
128. camelCase slots render inside q-layout/q-row/q-col
pending
Expected: Your heading here | Add a short supporting subtitle for this section. | Add supporting content or nested blocks here.
q-component t128-heading-block {
header {
h2 {
q-layout#t128-title-layout {
width: "100%"
gap: "8px"
q-row { q-col { slot { headingTitle } } }
}
}
p {
q-layout#t128-subtitle-layout {
width: "100%"
gap: "8px"
q-row { q-col { slot { headingSubtitle } } }
}
}
q-layout#t128-content-layout {
width: "100%"
gap: "8px"
q-row { q-col { slot { headingContent } } }
}
}
}
q-layout#t128-root {
width: "100%"
gap: "14px"
q-row {
height: "auto"
q-col {
width: "auto"
t128-heading-block {
headingTitle { text { Your heading here } }
headingSubtitle { text { Add a short supporting subtitle for this section. } }
headingContent { text { Add supporting content or nested blocks here. } }
}
}
}
}
div#t128-out { text { waiting } }
onReady {
var host = this;
setTimeout(function() {
var title = host.querySelector("#t128-title-layout q-col");
var subtitle = host.querySelector("#t128-subtitle-layout q-col");
var content = host.querySelector("#t128-content-layout q-col");
var actual = [
title ? String(title.textContent || "").trim() : "title-missing",
subtitle ? String(subtitle.textContent || "").trim() : "subtitle-missing",
content ? String(content.textContent || "").trim() : "content-missing"
].join(" | ");
var out = host.querySelector("#t128-out");
var acc = document.querySelector("#acc-main");
if (out) { out.textContent = actual; }
if (acc && typeof acc.outcomeReported === "function") {
acc.outcomeReported(128, actual === "Your heading here | Add a short supporting subtitle for this section. | Add supporting content or nested blocks here.", actual);
}
}, 120);
}
129. q-layout q-row stacks columns responsively
pending
Expected: stacked | wide
div#t129-box {
style { width: 260px; maxWidth: 100%; border: 1px solid #cbd5e1; padding: 6px; }
q-layout#t129-layout {
width: "100%"
gap: "8px"
q-row#t129-row {
stackAt: "360px"
gap: "8px"
q-col { width: "1fr" div { text { Left } } }
q-col { width: "1fr" div { text { Right } } }
}
}
}
div#t129-out { text { waiting } }
onReady {
var host = this;
setTimeout(function() {
var box = host.querySelector("#t129-box");
var row = host.querySelector("#t129-row");
var acc = document.querySelector("#acc-main");
var first = row && row.__qhtmlLayoutResponsiveStacked ? "stacked" : "not-stacked";
if (box) {
box.style.width = "520px";
}
if (row && typeof row.relayout === "function") {
row.relayout();
}
setTimeout(function() {
var second = row && !row.__qhtmlLayoutResponsiveStacked ? "wide" : "still-stacked";
var actual = first + " | " + second;
var out = host.querySelector("#t129-out");
if (out) { out.textContent = actual; }
if (acc && typeof acc.outcomeReported === "function") {
acc.outcomeReported(129, actual === "stacked | wide", actual);
}
}, 80);
}, 140);
}