FEATURE: Enable image grid by default (#22160)

This commit is contained in:
Penar Musaraj 2023-06-19 13:24:52 -04:00 committed by GitHub
parent fc11e77eff
commit f89b5680cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 176 additions and 57 deletions

View File

@ -777,9 +777,7 @@ export default Component.extend(
preview.addEventListener("click", this._handleAltTextCancelButtonClick); preview.addEventListener("click", this._handleAltTextCancelButtonClick);
preview.addEventListener("click", this._handleImageDeleteButtonClick); preview.addEventListener("click", this._handleImageDeleteButtonClick);
preview.addEventListener("keypress", this._handleAltTextInputKeypress); preview.addEventListener("keypress", this._handleAltTextInputKeypress);
if (this.siteSettings.experimental_post_image_grid) {
preview.addEventListener("click", this._handleImageGridButtonClick); preview.addEventListener("click", this._handleImageGridButtonClick);
}
}, },
@on("willDestroyElement") @on("willDestroyElement")
@ -806,9 +804,7 @@ export default Component.extend(
preview?.removeEventListener("click", this._handleAltTextEditButtonClick); preview?.removeEventListener("click", this._handleAltTextEditButtonClick);
preview?.removeEventListener("click", this._handleAltTextOkButtonClick); preview?.removeEventListener("click", this._handleAltTextOkButtonClick);
preview?.removeEventListener("click", this._handleImageDeleteButtonClick); preview?.removeEventListener("click", this._handleImageDeleteButtonClick);
if (this.siteSettings.experimental_post_image_grid) {
preview?.removeEventListener("click", this._handleImageGridButtonClick); preview?.removeEventListener("click", this._handleImageGridButtonClick);
}
preview?.removeEventListener( preview?.removeEventListener(
"click", "click",
this._handleAltTextCancelButtonClick this._handleAltTextCancelButtonClick

View File

@ -33,7 +33,6 @@ export default {
{ id: "discourse-lightbox" } { id: "discourse-lightbox" }
); );
if (siteSettings.experimental_post_image_grid) {
api.decorateCookedElement( api.decorateCookedElement(
(elem) => { (elem) => {
const grids = elem.querySelectorAll(".d-image-grid"); const grids = elem.querySelectorAll(".d-image-grid");
@ -50,7 +49,6 @@ export default {
}, },
{ id: "discourse-image-grid" } { id: "discourse-image-grid" }
); );
}
if (siteSettings.support_mixed_text_direction) { if (siteSettings.support_mixed_text_direction) {
api.decorateCookedElement(setTextDirections, { api.decorateCookedElement(setTextDirections, {

View File

@ -4,7 +4,6 @@
* *
* Inspired/adapted from https://github.com/mladenilic/columns.js * Inspired/adapted from https://github.com/mladenilic/columns.js
* *
* TODO: Add unit tests
*/ */
export default class Columns { export default class Columns {
constructor(container, options = {}) { constructor(container, options = {}) {
@ -12,13 +11,10 @@ export default class Columns {
this.options = { this.options = {
columns: 3, columns: 3,
columnClass: "d-image-grid-column",
minCount: 2, minCount: 2,
...options, ...options,
}; };
this.excluded = ["BR", "P"];
this.items = this._prepareItems(); this.items = this._prepareItems();
if (this.items.length >= this.options.minCount) { if (this.items.length >= this.options.minCount) {
@ -56,7 +52,7 @@ export default class Columns {
const columns = []; const columns = [];
[...Array(count)].forEach(() => { [...Array(count)].forEach(() => {
const column = document.createElement("div"); const column = document.createElement("div");
column.classList.add(this.options.columnClass); column.classList.add("d-image-grid-column");
columns.push(column); columns.push(column);
}); });
@ -78,7 +74,7 @@ export default class Columns {
}); });
return targets.filter((item) => { 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 // 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 img = item.querySelector("img") || item;
const aR = img.nodeName === "IMG" ? img.height / img.width : 1; const aR = img.nodeName === "IMG" ? img.height / img.width : 1;
columnHeights[shortest] += aR; columnHeights[shortest] += aR;

View File

@ -5,7 +5,6 @@ import { test } from "qunit";
acceptance("Composer - Image Grid", function (needs) { acceptance("Composer - Image Grid", function (needs) {
needs.user(); needs.user();
needs.settings({ needs.settings({
experimental_post_image_grid: true,
allow_uncategorized_topics: true, allow_uncategorized_topics: true,
}); });

View File

@ -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 = `<div class="d-image-grid">
<p><img src="/images/avatar.png" alt role="presentation"><br>
<img src="/images/avatar.png" alt role="presentation"><br>
<img src="/images/avatar.png" alt role="presentation"></p>
</div>`;
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 = `<div class="d-image-grid">
<p><img src="/images/avatar.png" alt role="presentation"><br>
<img src="/images/avatar.png" alt role="presentation"></p>
</div>`;
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 = `<div class="d-image-grid">
<img src="/images/avatar.png" width="20" height="20" role="presentation">
<img src="/images/avatar.png" width="20" height="20" role="presentation">
<img src="/images/avatar.png" width="20" height="20" role="presentation">
<img src="/images/avatar.png" width="20" height="20" role="presentation">
</div>`;
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 = `<div class="d-image-grid">
<img src="/images/avatar.png" width="20" height="20" role="presentation">
<img src="/images/avatar.png" width="20" height="20" role="presentation">
<img src="/images/avatar.png" width="20" height="20" role="presentation">
<div style="width: 20px; height: 20px; background-color: red;">hey there</div>
<div style="width: 20px; height: 20px; background-color: red;">hey there</div>
</div>`;
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"
);
});
});

View File

@ -1754,28 +1754,18 @@ var bar = 'bar';
test("image grid", function (assert) { test("image grid", function (assert) {
assert.cooked( assert.cooked(
"[grid]\n![](http://folksy.com/images/folksy-colour.png)\n[/grid]", "[grid]\n![](http://folksy.com/images/folksy-colour.png)\n[/grid]",
`<p>[grid]<br>
<img src="http://folksy.com/images/folksy-colour.png" alt role="presentation"><br>
[/grid]</p>`,
"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 } },
`<div class="d-image-grid"> `<div class="d-image-grid">
<p><img src="http://folksy.com/images/folksy-colour.png" alt role="presentation"></p> <p><img src="http://folksy.com/images/folksy-colour.png" alt role="presentation"></p>
</div>`, </div>`,
"image grid with site setting works" "image grid works"
); );
assert.cookedOptions( assert.cooked(
`[grid] `[grid]
![](http://folksy.com/images/folksy-colour.png) ![](http://folksy.com/images/folksy-colour.png)
![](http://folksy.com/images/folksy-colour2.png) ![](http://folksy.com/images/folksy-colour2.png)
![](http://folksy.com/images/folksy-colour3.png) ![](http://folksy.com/images/folksy-colour3.png)
[/grid]`, [/grid]`,
{ siteSettings: { experimental_post_image_grid: true } },
`<div class="d-image-grid"> `<div class="d-image-grid">
<p><img src="http://folksy.com/images/folksy-colour.png" alt role="presentation"><br> <p><img src="http://folksy.com/images/folksy-colour.png" alt role="presentation"><br>
<img src="http://folksy.com/images/folksy-colour2.png" alt role="presentation"><br> <img src="http://folksy.com/images/folksy-colour2.png" alt role="presentation"><br>
@ -1784,12 +1774,11 @@ var bar = 'bar';
"image grid with 3 images works" "image grid with 3 images works"
); );
assert.cookedOptions( assert.cooked(
`[grid] `[grid]
![](http://folksy.com/images/folksy-colour.png) ![](http://folksy.com/images/folksy-colour2.png) ![](http://folksy.com/images/folksy-colour.png) ![](http://folksy.com/images/folksy-colour2.png)
![](http://folksy.com/images/folksy-colour3.png) ![](http://folksy.com/images/folksy-colour3.png)
[/grid]`, [/grid]`,
{ siteSettings: { experimental_post_image_grid: true } },
`<div class="d-image-grid"> `<div class="d-image-grid">
<p><img src="http://folksy.com/images/folksy-colour.png" alt role="presentation"> <img src="http://folksy.com/images/folksy-colour2.png" alt role="presentation"><br> <p><img src="http://folksy.com/images/folksy-colour.png" alt role="presentation"> <img src="http://folksy.com/images/folksy-colour2.png" alt role="presentation"><br>
<img src="http://folksy.com/images/folksy-colour3.png" alt role="presentation"></p> <img src="http://folksy.com/images/folksy-colour3.png" alt role="presentation"></p>
@ -1797,9 +1786,8 @@ var bar = 'bar';
"image grid with mixed block and inline images works" "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]", "[grid]![](http://folksy.com/images/folksy-colour.png) ![](http://folksy.com/images/folksy-colour2.png)[/grid]",
{ siteSettings: { experimental_post_image_grid: true } },
`<div class="d-image-grid"> `<div class="d-image-grid">
<p><img src="http://folksy.com/images/folksy-colour.png" alt role="presentation"> <img src="http://folksy.com/images/folksy-colour2.png" alt role="presentation"></p> <p><img src="http://folksy.com/images/folksy-colour.png" alt role="presentation"> <img src="http://folksy.com/images/folksy-colour2.png" alt role="presentation"></p>
</div>`, </div>`,

View File

@ -11,17 +11,9 @@ const gridRule = {
}; };
export function setup(helper) { export function setup(helper) {
helper.registerOptions((opts, siteSettings) => {
opts.enableGrid = !!siteSettings.experimental_post_image_grid;
});
helper.allowList(["div.d-image-grid"]); helper.allowList(["div.d-image-grid"]);
helper.registerPlugin((md) => { helper.registerPlugin((md) => {
if (!md.options.discourse.enableGrid) {
return;
}
md.block.bbcode.ruler.push("grid", gridRule); md.block.bbcode.ruler.push("grid", gridRule);
}); });
} }

View File

@ -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.' 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" enable_custom_sidebar_sections: "EXPERIMENTAL: Enable custom sidebar sections"
experimental_topics_filter: "EXPERIMENTAL: Enables the experimental topics filter route at /filter" 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" experimental_search_menu_groups: "EXPERIMENTAL: Enables the new search menu that has been upgraded to use glimmer"
errors: errors:

View File

@ -2112,9 +2112,6 @@ developer:
experimental_topics_filter: experimental_topics_filter:
client: true client: true
default: false default: false
experimental_post_image_grid:
client: true
default: false
new_edit_sidebar_categories_tags_interface_groups: new_edit_sidebar_categories_tags_interface_groups:
type: group_list type: group_list
list_type: compact list_type: compact