FEATURE: Enable image grid by default (#22160)
This commit is contained in:
parent
fc11e77eff
commit
f89b5680cb
|
@ -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
|
||||||
|
|
|
@ -33,24 +33,22 @@ 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");
|
|
||||||
|
|
||||||
if (!grids.length) {
|
if (!grids.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
grids.forEach((grid) => {
|
grids.forEach((grid) => {
|
||||||
return new Columns(grid, {
|
return new Columns(grid, {
|
||||||
columns: site.mobileView ? 2 : 3,
|
columns: site.mobileView ? 2 : 3,
|
||||||
});
|
|
||||||
});
|
});
|
||||||
},
|
});
|
||||||
{ 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, {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
|
@ -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>`,
|
||||||
|
|
|
@ -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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue