Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions src/js/core/RowManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -893,10 +893,19 @@ export default class RowManager extends CoreFeature{
}

if(renderClass){
this.renderMode = this.table.options.renderVertical;

this.renderer = new renderClass(this.table, this.element, this.tableElement);
this.renderer.initialize();

//renderMode must be a STRING: it is written into the
//tabulator-render-mode DOM attribute (see _showPlaceholder) and
//returned by getRenderMode(). options.renderVertical may be a custom
//renderer CLASS rather than a "virtual"/"basic" key; assigning it
//verbatim stringified the whole class source into the attribute.
//Prefer the resolved string key, else the renderer's own declared
//string renderMode, else fall back to "virtual".
this.renderMode = typeof this.table.options.renderVertical === "string"
? this.table.options.renderVertical
: (typeof this.renderer.renderMode === "string" ? this.renderer.renderMode : "virtual");

if((this.table.element.clientHeight || this.table.options.height) && !(this.table.options.minHeight && this.table.options.maxHeight)){
this.fixedHeight = true;
Expand Down
62 changes: 62 additions & 0 deletions test/unit/core/RowManager.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import TabulatorFull from "../../../src/js/core/TabulatorFull";
import VirtualDomVertical from "../../../src/js/core/rendering/renderers/VirtualDomVertical.js";

// Regression: RowManager stored options.renderVertical verbatim in renderMode.
// When a custom renderer CLASS was passed (renderVertical: SomeRenderer), the
// class was later stringified into the tabulator-render-mode DOM attribute
// (RowManager._showPlaceholder) and returned by getRenderMode() as a function
// rather than a mode string.
describe("RowManager renderMode", () => {
let el;

beforeEach(() => {
el = document.createElement("div");
document.body.appendChild(el);
});

afterEach(() => {
el.remove();
});

const build = (options) =>
new Promise((resolve) => {
const table = new TabulatorFull(el, options);
table.on("tableBuilt", () => resolve(table));
});

test("string renderVertical is recorded verbatim", async () => {
const table = await build({
renderVertical: "virtual",
placeholder: "No Data",
data: [],
columns: [{ title: "A", field: "a" }],
});

expect(table.rowManager.getRenderMode()).toBe("virtual");
});

test("custom renderer class resolves to a string mode, not the class source", async () => {
class CustomRenderer extends VirtualDomVertical {}

const table = await build({
renderVertical: CustomRenderer,
placeholder: "No Data",
data: [],
columns: [{ title: "A", field: "a" }],
});

const mode = table.rowManager.getRenderMode();
expect(typeof mode).toBe("string");
expect(mode).toBe("virtual");

// The mode is written into the tabulator-render-mode DOM attribute; before
// the fix this held the stringified class body. Show the placeholder so
// the attribute is actually written.
table.rowManager.tableEmpty();
const placeholder = table.element.querySelector("[tabulator-render-mode]");
expect(placeholder).not.toBeNull();
const attr = placeholder.getAttribute("tabulator-render-mode");
expect(attr).toBe("virtual");
expect(attr).not.toMatch(/class |function |=>/);
});
});
Loading