diff --git a/app/assets/javascripts/discourse/app/components/composer-editor.js b/app/assets/javascripts/discourse/app/components/composer-editor.js
index c95a3e35469..1d46e8194d7 100644
--- a/app/assets/javascripts/discourse/app/components/composer-editor.js
+++ b/app/assets/javascripts/discourse/app/components/composer-editor.js
@@ -777,9 +777,7 @@ export default Component.extend(
preview.addEventListener("click", this._handleAltTextCancelButtonClick);
preview.addEventListener("click", this._handleImageDeleteButtonClick);
preview.addEventListener("keypress", this._handleAltTextInputKeypress);
- if (this.siteSettings.experimental_post_image_grid) {
- preview.addEventListener("click", this._handleImageGridButtonClick);
- }
+ preview.addEventListener("click", this._handleImageGridButtonClick);
},
@on("willDestroyElement")
@@ -806,9 +804,7 @@ export default Component.extend(
preview?.removeEventListener("click", this._handleAltTextEditButtonClick);
preview?.removeEventListener("click", this._handleAltTextOkButtonClick);
preview?.removeEventListener("click", this._handleImageDeleteButtonClick);
- if (this.siteSettings.experimental_post_image_grid) {
- preview?.removeEventListener("click", this._handleImageGridButtonClick);
- }
+ preview?.removeEventListener("click", this._handleImageGridButtonClick);
preview?.removeEventListener(
"click",
this._handleAltTextCancelButtonClick
diff --git a/app/assets/javascripts/discourse/app/instance-initializers/post-decorations.js b/app/assets/javascripts/discourse/app/instance-initializers/post-decorations.js
index a43b7aa3288..c5361315a79 100644
--- a/app/assets/javascripts/discourse/app/instance-initializers/post-decorations.js
+++ b/app/assets/javascripts/discourse/app/instance-initializers/post-decorations.js
@@ -33,24 +33,22 @@ export default {
{ id: "discourse-lightbox" }
);
- if (siteSettings.experimental_post_image_grid) {
- api.decorateCookedElement(
- (elem) => {
- const grids = elem.querySelectorAll(".d-image-grid");
+ api.decorateCookedElement(
+ (elem) => {
+ const grids = elem.querySelectorAll(".d-image-grid");
- if (!grids.length) {
- return;
- }
+ if (!grids.length) {
+ return;
+ }
- grids.forEach((grid) => {
- return new Columns(grid, {
- columns: site.mobileView ? 2 : 3,
- });
+ grids.forEach((grid) => {
+ return new Columns(grid, {
+ columns: site.mobileView ? 2 : 3,
});
- },
- { id: "discourse-image-grid" }
- );
- }
+ });
+ },
+ { id: "discourse-image-grid" }
+ );
if (siteSettings.support_mixed_text_direction) {
api.decorateCookedElement(setTextDirections, {
diff --git a/app/assets/javascripts/discourse/app/lib/columns.js b/app/assets/javascripts/discourse/app/lib/columns.js
index b0ebdf106a6..3654748b987 100644
--- a/app/assets/javascripts/discourse/app/lib/columns.js
+++ b/app/assets/javascripts/discourse/app/lib/columns.js
@@ -4,7 +4,6 @@
*
* Inspired/adapted from https://github.com/mladenilic/columns.js
*
- * TODO: Add unit tests
*/
export default class Columns {
constructor(container, options = {}) {
@@ -12,13 +11,10 @@ export default class Columns {
this.options = {
columns: 3,
- columnClass: "d-image-grid-column",
minCount: 2,
...options,
};
- this.excluded = ["BR", "P"];
-
this.items = this._prepareItems();
if (this.items.length >= this.options.minCount) {
@@ -56,7 +52,7 @@ export default class Columns {
const columns = [];
[...Array(count)].forEach(() => {
const column = document.createElement("div");
- column.classList.add(this.options.columnClass);
+ column.classList.add("d-image-grid-column");
columns.push(column);
});
@@ -78,7 +74,7 @@ export default class Columns {
});
return targets.filter((item) => {
- return !this.excluded.includes(item.nodeName);
+ return !["BR", "P"].includes(item.nodeName);
});
}
@@ -111,7 +107,7 @@ export default class Columns {
}
// use aspect ratio to compare heights and append to shortest column
- // if element is not an image, assue ratio is 1:1
+ // if element is not an image, assume ratio is 1:1
const img = item.querySelector("img") || item;
const aR = img.nodeName === "IMG" ? img.height / img.width : 1;
columnHeights[shortest] += aR;
diff --git a/app/assets/javascripts/discourse/tests/acceptance/composer-image-grid-test.js b/app/assets/javascripts/discourse/tests/acceptance/composer-image-grid-test.js
index db62b7ed704..f41476d67ca 100644
--- a/app/assets/javascripts/discourse/tests/acceptance/composer-image-grid-test.js
+++ b/app/assets/javascripts/discourse/tests/acceptance/composer-image-grid-test.js
@@ -5,7 +5,6 @@ import { test } from "qunit";
acceptance("Composer - Image Grid", function (needs) {
needs.user();
needs.settings({
- experimental_post_image_grid: true,
allow_uncategorized_topics: true,
});
diff --git a/app/assets/javascripts/discourse/tests/unit/lib/columns-test.js b/app/assets/javascripts/discourse/tests/unit/lib/columns-test.js
new file mode 100644
index 00000000000..59fa6985675
--- /dev/null
+++ b/app/assets/javascripts/discourse/tests/unit/lib/columns-test.js
@@ -0,0 +1,154 @@
+import { module, test } from "qunit";
+import Columns from "discourse/lib/columns";
+
+module("Unit | Columns", function (hooks) {
+ hooks.afterEach(function () {
+ document.getElementById("qunit-fixture").innerHTML = "";
+ });
+
+ test("works", function (assert) {
+ document.getElementById(
+ "qunit-fixture"
+ ).innerHTML = `
`;
+
+ const grid = document.querySelector(".d-image-grid");
+ const cols = new Columns(grid);
+ assert.strictEqual(cols.items.length, 3);
+
+ assert.strictEqual(
+ grid.dataset.columns,
+ "3",
+ "column count attribute is correct"
+ );
+
+ assert.strictEqual(
+ document.querySelectorAll(".d-image-grid > .d-image-grid-column").length,
+ 3,
+ "three column elements are rendered"
+ );
+ });
+
+ test("disabled if items < minCount", function (assert) {
+ document.getElementById(
+ "qunit-fixture"
+ ).innerHTML = `
+
+
+
`;
+
+ const grid = document.querySelector(".d-image-grid");
+ const cols = new Columns(grid, { minCount: 3 });
+
+ assert.strictEqual(cols.items.length, 2);
+
+ assert.strictEqual(
+ grid.dataset.disabled,
+ "true",
+ "disabled attribute is added"
+ );
+ assert.strictEqual(
+ document.querySelectorAll(".d-image-grid > .d-image-grid-column").length,
+ 0,
+ "no column elements are rendered"
+ );
+ });
+
+ test("4 items shown in 2x2 grid", function (assert) {
+ document.getElementById(
+ "qunit-fixture"
+ ).innerHTML = ``;
+
+ const grid = document.querySelector(".d-image-grid");
+ const cols = new Columns(grid);
+
+ assert.strictEqual(cols.items.length, 4);
+ assert.strictEqual(
+ grid.dataset.columns,
+ "2",
+ "column count attribute is correct"
+ );
+ assert.strictEqual(
+ document.querySelectorAll(".d-image-grid > .d-image-grid-column").length,
+ 2,
+ "two columns are rendered"
+ );
+
+ assert.strictEqual(
+ document.querySelectorAll(
+ ".d-image-grid > .d-image-grid-column:first-child .image-wrapper"
+ ).length,
+ 2,
+ "two images in column 1"
+ );
+
+ assert.strictEqual(
+ document.querySelectorAll(
+ ".d-image-grid > .d-image-grid-column:nth-child(2) .image-wrapper"
+ ).length,
+ 2,
+ "two images in column 2"
+ );
+ });
+
+ test("non-image elements", function (assert) {
+ document.getElementById(
+ "qunit-fixture"
+ ).innerHTML = `
+
+
+
+
hey there
+
hey there
+
`;
+
+ const grid = document.querySelector(".d-image-grid");
+ const cols = new Columns(grid);
+
+ assert.strictEqual(cols.items.length, 5);
+ assert.strictEqual(cols.container, grid);
+
+ assert.strictEqual(
+ grid.dataset.columns,
+ "3",
+ "column count attribute is correct"
+ );
+ assert.strictEqual(
+ document.querySelectorAll(".d-image-grid > .d-image-grid-column").length,
+ 3,
+ "three columns are rendered"
+ );
+
+ assert.strictEqual(
+ document.querySelectorAll(
+ ".d-image-grid > .d-image-grid-column:first-child > *"
+ ).length,
+ 2,
+ "two elements in column 1"
+ );
+
+ assert.strictEqual(
+ document.querySelectorAll(
+ ".d-image-grid > .d-image-grid-column:nth-child(2) > *"
+ ).length,
+ 2,
+ "two elements in column 2"
+ );
+
+ assert.strictEqual(
+ document.querySelectorAll(
+ ".d-image-grid > .d-image-grid-column:nth-child(3) > *"
+ ).length,
+ 1,
+ "one element in column 3"
+ );
+ });
+});
diff --git a/app/assets/javascripts/discourse/tests/unit/lib/pretty-text-test.js b/app/assets/javascripts/discourse/tests/unit/lib/pretty-text-test.js
index fe3b06b8be5..c909f43b9ac 100644
--- a/app/assets/javascripts/discourse/tests/unit/lib/pretty-text-test.js
+++ b/app/assets/javascripts/discourse/tests/unit/lib/pretty-text-test.js
@@ -1754,28 +1754,18 @@ var bar = 'bar';
test("image grid", function (assert) {
assert.cooked(
"[grid]\n![](http://folksy.com/images/folksy-colour.png)\n[/grid]",
- `[grid]
-
-[/grid]
`,
- "image grid without site setting does not work"
- );
-
- assert.cookedOptions(
- "[grid]\n![](http://folksy.com/images/folksy-colour.png)\n[/grid]",
- { siteSettings: { experimental_post_image_grid: true } },
`
`,
- "image grid with site setting works"
+ "image grid works"
);
- assert.cookedOptions(
+ assert.cooked(
`[grid]
![](http://folksy.com/images/folksy-colour.png)
![](http://folksy.com/images/folksy-colour2.png)
![](http://folksy.com/images/folksy-colour3.png)
[/grid]`,
- { siteSettings: { experimental_post_image_grid: true } },
`
@@ -1784,12 +1774,11 @@ var bar = 'bar';
"image grid with 3 images works"
);
- assert.cookedOptions(
+ assert.cooked(
`[grid]
![](http://folksy.com/images/folksy-colour.png) ![](http://folksy.com/images/folksy-colour2.png)
![](http://folksy.com/images/folksy-colour3.png)
[/grid]`,
- { siteSettings: { experimental_post_image_grid: true } },
`
@@ -1797,9 +1786,8 @@ var bar = 'bar';
"image grid with mixed block and inline images works"
);
- assert.cookedOptions(
+ assert.cooked(
"[grid]![](http://folksy.com/images/folksy-colour.png) ![](http://folksy.com/images/folksy-colour2.png)[/grid]",
- { siteSettings: { experimental_post_image_grid: true } },
`
`,
diff --git a/app/assets/javascripts/pretty-text/engines/discourse-markdown/image-grid.js b/app/assets/javascripts/pretty-text/engines/discourse-markdown/image-grid.js
index 7e6b2626399..c55b3543fa3 100644
--- a/app/assets/javascripts/pretty-text/engines/discourse-markdown/image-grid.js
+++ b/app/assets/javascripts/pretty-text/engines/discourse-markdown/image-grid.js
@@ -11,17 +11,9 @@ const gridRule = {
};
export function setup(helper) {
- helper.registerOptions((opts, siteSettings) => {
- opts.enableGrid = !!siteSettings.experimental_post_image_grid;
- });
-
helper.allowList(["div.d-image-grid"]);
helper.registerPlugin((md) => {
- if (!md.options.discourse.enableGrid) {
- return;
- }
-
md.block.bbcode.ruler.push("grid", gridRule);
});
}
diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
index 63d364b9e7b..71bb90ae97b 100644
--- a/config/locales/server.en.yml
+++ b/config/locales/server.en.yml
@@ -2430,7 +2430,6 @@ en:
experimental_new_new_view_groups: 'EXPERIMENTAL: Enable a new topics list that combines unread and new topics and make the "Everything" link in the sidebar link to it.'
enable_custom_sidebar_sections: "EXPERIMENTAL: Enable custom sidebar sections"
experimental_topics_filter: "EXPERIMENTAL: Enables the experimental topics filter route at /filter"
- experimental_post_image_grid: "EXPERIMENTAL: Enables a [grid] tag in posts to display images in a grid layout."
experimental_search_menu_groups: "EXPERIMENTAL: Enables the new search menu that has been upgraded to use glimmer"
errors:
diff --git a/config/site_settings.yml b/config/site_settings.yml
index f21a88baeeb..9244d50286c 100644
--- a/config/site_settings.yml
+++ b/config/site_settings.yml
@@ -2112,9 +2112,6 @@ developer:
experimental_topics_filter:
client: true
default: false
- experimental_post_image_grid:
- client: true
- default: false
new_edit_sidebar_categories_tags_interface_groups:
type: group_list
list_type: compact