Skip to content

Commit 2a9558d

Browse files
committed
Remove the table hookup form from regions.mount now that tables mount as registered cards; prompt for the commit message when push.py is run without one
1 parent 718ea8c commit 2a9558d

10 files changed

Lines changed: 120 additions & 218 deletions

File tree

‎juneau-rest/juneau-rest-server-views/src/main/resources/org/apache/juneau/views/juneau-regions.js‎

Lines changed: 15 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1722,22 +1722,20 @@
17221722
}
17231723

17241724
/**
1725-
* Binds author-HTML slot ids to registered region populators and/or table widgets.
1725+
* Binds author-HTML slot ids to registered region populators.
17261726
*
1727-
* HTML ids are places. A string value is a registered populator name. A `{ table: url | inlineEnvelope }`
1728-
* value mounts a table widget into that empty slot. The string `"juneau-table"` is not a populator and
1729-
* throws. Missing element ids, blank names, unregistered populators, and unrecognized value shapes fail
1730-
* loud and enrol nothing on the page - they do not skip the bad entry and they do not fall through to
1731-
* defaultPopulate.
1727+
* HTML ids are places. A value is a registered populator name; tables mount as `<@card type="datatables">`,
1728+
* not through this call. Missing element ids, blank names, unregistered populators, and unrecognized value
1729+
* shapes fail loud and enrol nothing on the page - they do not skip the bad entry and they do not fall
1730+
* through to defaultPopulate.
17321731
*
17331732
* Region enrolment is synchronous through initRegion (populate has already run before the returned
1734-
* thenable is handed back). Table entries are fetched/inited asynchronously. The return is a thenable
1735-
* that resolves to the region-handle array (map-key order among region entries). A table fetch/handshake
1736-
* failure paints a banner in that slot and does not unroll already-enrolled regions.
1733+
* thenable is handed back). The return is a thenable that resolves to the region-handle array (map-key
1734+
* order).
17371735
*
17381736
* Bus targeting `{to: slotId}` uses the slot id (the map key), which is the region id after mount.
17391737
*
1740-
* @param {Object<string, string|{table: string|Object}>} hookup Map of element id → populator name or table binding.
1738+
* @param {Object<string, string>} hookup Map of element id → populator name.
17411739
* @returns {Promise<Array>} Thenable resolving to the region handles initRegion minted.
17421740
*/
17431741
function mount(hookup) { // NOSONAR javascript:S3776 -- encodes a views/widgets state machine; complexity is inherent
@@ -1757,12 +1755,6 @@
17571755
window.console.error(message);
17581756
throw new Error(message);
17591757
}
1760-
if (value === "juneau-table") {
1761-
const message = "JuneauViews.regions.mount: the string 'juneau-table' is not a populator; "
1762-
+ "use { table: url } (or an inline envelope) as the slot value.";
1763-
window.console.error(message);
1764-
throw new Error(message);
1765-
}
17661758
if (typeof value === "string") {
17671759
const name = value;
17681760
if (blank(name)) {
@@ -1779,73 +1771,19 @@
17791771
planned.push({ kind: "region", el: el, id: id, name: name });
17801772
continue;
17811773
}
1782-
if (value != null && typeof value === "object" && !Array.isArray(value) && Object.hasOwn(value, "table")) {
1783-
const table = value.table;
1784-
if (typeof table === "string") {
1785-
if (blank(table)) {
1786-
const message = "JuneauViews.regions.mount: slot '" + id + "' has a blank or missing table URL.";
1787-
window.console.error(message);
1788-
throw new Error(message);
1789-
}
1790-
planned.push({ kind: "table", el: el, id: id, table: table });
1791-
continue;
1792-
}
1793-
if (table != null && typeof table === "object" && !Array.isArray(table)) {
1794-
planned.push({ kind: "table", el: el, id: id, table: table });
1795-
continue;
1796-
}
1797-
}
17981774
const message = "JuneauViews.regions.mount: slot '" + id + "' has an unrecognized binding "
1799-
+ "(expected a populator name or { table: url | envelope }).";
1775+
+ "(expected a populator name).";
18001776
window.console.error(message);
18011777
throw new Error(message);
18021778
}
18031779
const handles = [];
1804-
const tableJobs = [];
1805-
for (const plannedItem of planned) {
1806-
const item = plannedItem;
1807-
if (item.kind === "region") {
1808-
item.el.setAttribute(REGION_ATTR, item.id);
1809-
item.el.setAttribute(REGION_POPULATE_ATTR, item.name);
1810-
const handle = initRegion(item.el);
1811-
if (handle) handles.push(handle);
1812-
continue;
1813-
}
1814-
tableJobs.push(mountTableSlot(item.el, item.table));
1780+
for (const item of planned) {
1781+
item.el.setAttribute(REGION_ATTR, item.id);
1782+
item.el.setAttribute(REGION_POPULATE_ATTR, item.name);
1783+
const handle = initRegion(item.el);
1784+
if (handle) handles.push(handle);
18151785
}
1816-
const done = tableJobs.length ? Promise.all(tableJobs) : Promise.resolve();
1817-
return done.then(function () { return handles; });
1818-
}
1819-
1820-
/**
1821-
* Delegates table-slot construction to juneau-views.js. Fetch/handshake failures are swallowed here so
1822-
* Promise.all still resolves (the views helper paints the slot banner). A missing helper is a banner +
1823-
* console.error, not an unroll of already-enrolled regions.
1824-
*/
1825-
function mountTableSlot(slot, tableValue) {
1826-
const init = window.JuneauViews?.init;
1827-
if (!init || typeof init.mountTableSlot !== "function") {
1828-
const message = "JuneauViews.regions.mount: table slots require JuneauViews.init.mountTableSlot.";
1829-
window.console.error(message);
1830-
paintMountBanner(slot, message);
1831-
return Promise.resolve();
1832-
}
1833-
return Promise.resolve()
1834-
.then(function () { return init.mountTableSlot(slot, tableValue); })
1835-
.catch(function (err) {
1836-
const message = String(err?.message ? err.message : err);
1837-
window.console.error("JuneauViews.regions.mount: table slot failed: " + message);
1838-
paintMountBanner(slot, message);
1839-
});
1840-
}
1841-
1842-
function paintMountBanner(slot, message) {
1843-
if (!slot) return;
1844-
slot.textContent = "";
1845-
const p = window.document.createElement("p");
1846-
p.className = "juneau-view-error";
1847-
p.textContent = message;
1848-
slot.appendChild(p);
1786+
return Promise.resolve(handles);
18491787
}
18501788

18511789
// ==================================================================================================================

‎juneau-rest/juneau-rest-server-views/src/test/java/org/apache/juneau/rest/server/views/Regions_Mount_Test.java‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ private static void assertAllTrue(Map<?,?> r, String... keys) {
5151
assertFalse(body.contains("NS.pages.mount"), "mount must not publish under NS.pages");
5252
assertTrue(body.contains("no populator is registered under the name"), body);
5353
assertTrue(body.contains("no element with id"), body);
54-
assertTrue(body.contains("the string 'juneau-table' is not a populator"), body);
55-
assertTrue(body.contains("{ table: url }"), body);
54+
assertFalse(body.contains("is not a populator"), "the juneau-table guard is retired");
55+
assertFalse(body.contains("{ table: url"), "the table hookup form is retired");
5656
}
5757

5858
@Test void a02_sourceShape_mountDoesNotFallThroughToDefaultPopulate() throws Exception {
@@ -105,9 +105,9 @@ private static void assertAllTrue(Map<?,?> r, String... keys) {
105105
assertAllTrue(r, "t6_pageNavNotExported", "t6_authorAriaPreserved", "t6_noSelectedClass", "t6_noPillClass");
106106
}
107107

108-
@Test void b07_juneauTableStringThrowsNewMessageAndEnrolsNothing() {
108+
@Test void b07_retiredTableFormAndJuneauTableStringAreRejectedAndEnrolNothing() {
109109
var r = report();
110-
assertAllTrue(r, "t7_threw", "t7_pointsAtTableUrl", "t7_notUnregisteredName", "t7_consoleError",
110+
assertAllTrue(r, "t7_tableFormRejectedAsUnrecognized", "t7_juneauTableStringRejectedAsUnknownPopulator",
111111
"t7_notStamped", "t7_defaultDidNotRun");
112112
}
113113
}

‎juneau-rest/juneau-rest-server-views/src/test/java/org/apache/juneau/rest/server/views/ViewsJs_SlotMount_Test.java‎

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -110,17 +110,6 @@ private static String viewsJs() throws IOException {
110110
assertAllTrue(r, "t5_urlUsed", "t5_tableFromUrl");
111111
}
112112

113-
@Test void b06_blankTableUrlThrowsWithoutFetch() {
114-
var r = report();
115-
assertAllTrue(r, "t6_blankThrew", "t6_blankNamesUrl", "t6_blankNoFetch", "t6_blankLogged",
116-
"t6_blankNotStamped", "t7_wsThrew", "t7_wsNoFetch");
117-
}
118-
119-
@Test void b07_missingIdOrBadShapeEnrolsNothing() {
120-
var r = report();
121-
assertAllTrue(r, "t8_missingIdThrew", "t8_probesNotStamped", "t9_badShapeThrew", "t9_probesNotStamped");
122-
}
123-
124113
@Test void b08_csrfCopiedFromAncestorNotFromSsc() {
125114
var r = report();
126115
assertAllTrue(r, "t10_csrfCopied", "t10_csrfHeaderCopied", "t11_noJuneauToken",

‎juneau-rest/juneau-rest-server-views/src/test/js/detail-region-params.cjs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ function envelope(NS, region) {
6161
async function build(region) {
6262
const ctx = H.load(rendersJsPath, viewsJsPath, regionsJsPath);
6363
const host = slot(ctx.env, 'runs-slot');
64-
await Promise.resolve(ctx.R.mount({ 'runs-slot': { table: envelope(ctx.NS, region) } }));
64+
await Promise.resolve(ctx.NS.init.mountTableSlot(host, envelope(ctx.NS, region)));
6565
const tpl = host.querySelector('template[data-juneau-row-detail]');
6666
const content = tpl && tpl.content ? tpl.content : null;
6767
ctx.region = content ? content.querySelector('[data-juneau-region="' + region.id + '"]') : null;

‎juneau-rest/juneau-rest-server-views/src/test/js/regions-mount.cjs‎

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -227,25 +227,31 @@ function slot(env, id) {
227227
}
228228

229229
// =================================================================================================================
230-
// String "juneau-table" throws a NEW message pointing at { table: url }; enrols nothing.
230+
// The retired { table: ... } hookup form is an unrecognized binding, and "juneau-table" is just an unknown
231+
// populator name; neither enrols anything.
231232
// =================================================================================================================
232233
{
233234
const { env, R, rec } = H.load(rendersJsPath, viewsJsPath, regionsJsPath);
234235
let defaultRan = false;
235236
R.builtins.default = function () { defaultRan = true; };
236237
const incidents = slot(env, 'incidents');
237-
let threw = false;
238-
let message = '';
238+
let tableMessage = '';
239+
try {
240+
R.mount({ incidents: { table: '/x' } });
241+
} catch (error) {
242+
tableMessage = String(error?.message ? error.message : error);
243+
}
244+
out.t7_tableFormRejectedAsUnrecognized = tableMessage.indexOf('has an unrecognized binding') >= 0
245+
&& rec.errorsMatching('unrecognized binding').length >= 1;
246+
let stringMessage = '';
239247
try {
240248
R.mount({ incidents: 'juneau-table' });
241249
} catch (error) {
242-
threw = true;
243-
message = String(error?.message ? error.message : error);
250+
stringMessage = String(error?.message ? error.message : error);
244251
}
245-
out.t7_threw = threw;
246-
out.t7_pointsAtTableUrl = message.indexOf('{ table: url }') >= 0;
247-
out.t7_notUnregisteredName = message.indexOf('no populator is registered under the name') < 0;
248-
out.t7_consoleError = rec.errorsMatching('juneau-table').length >= 1;
252+
out.t7_juneauTableStringRejectedAsUnknownPopulator
253+
= stringMessage.indexOf("no populator is registered under the name 'juneau-table'") >= 0
254+
&& rec.errorsMatching('juneau-table').length >= 1;
249255
out.t7_notStamped = incidents.dataset.juneauRegion == null;
250256
out.t7_defaultDidNotRun = defaultRan === false;
251257
}

‎juneau-rest/juneau-rest-server-views/src/test/js/slot-detail-chevron-browser.cjs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
*
2626
* Chromium is the subject: buildDetailTemplate must paint into tpl.content (the fragment expandDetailRow clones).
2727
* template.appendChild leaves that fragment empty in Chromium, which expands to a ~26px blank gap. The fixture
28-
* is a ViewSlot envelope mounted through JuneauViews.regions.mount({ table }), so the template under test is the
28+
* is a ViewSlot envelope mounted through JuneauViews.init.mountTableSlot, so the template under test is the
2929
* production slot path. No jQuery/DataTables is provisioned for this profile: after mount, the prober synthesizes
3030
* one body row with the production chevron markup and a DataTables child-row stand-in, matching TableClipFree.
3131
* Prints ONE JSON object to stdout; every assertion is in Java.
@@ -58,7 +58,7 @@ const PROBE = async function () {
5858
// The canary's RegionDef.populate("p") is a named populator; register a stub so chevron expand
5959
// does not console.error "no populator is registered under the name 'p'" into jsFailures.
6060
R.register('p', function () { /* stub: region-only DETAIL_SLOT chrome is what this canary asserts */ });
61-
await Promise.resolve(R.mount({ gacks: { table: envelope } }));
61+
await Promise.resolve(NS.init.mountTableSlot(slot, envelope));
6262

6363
const tpl = slot.querySelector('template[data-juneau-row-detail]');
6464
const dest = tpl?.content ? tpl.content : null;

0 commit comments

Comments
 (0)