DEV: Allow utility class domFromString to take in strings with multiple top level elements (#15548)

Previously only `<div>one top element</div>` was allowed because we use `firstChild` instead of `children`.
We also want `<div>one</div><div>two</div>` to work with this method.
This commit is contained in:
Natalie Tay 2022-01-12 19:49:24 +08:00 committed by GitHub
parent 252bb87ab3
commit dd3ed27930
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 17 additions and 14 deletions

View File

@ -2,5 +2,5 @@ export default function domFromString(string) {
const template = document.createElement("template"); const template = document.createElement("template");
string = string.trim(); string = string.trim();
template.innerHTML = string; template.innerHTML = string;
return template.content.firstChild; return template.content.children;
} }

View File

@ -4,7 +4,10 @@ import domFromString from "discourse-common/lib/dom-from-string";
discourseModule("Unit | Utility | domFromString", function () { discourseModule("Unit | Utility | domFromString", function () {
test("constructing DOM node from a string", function (assert) { test("constructing DOM node from a string", function (assert) {
const node = domFromString('<div class="foo">foo</div>'); const node = domFromString(
assert.ok(node.classList.contains("foo")); '<div class="foo">foo</div><div class="boo">boo</div>'
);
assert.ok(node[0].classList.contains("foo"));
assert.ok(node[1].classList.contains("boo"));
}); });
}); });

View File

@ -38,7 +38,7 @@ function shortDateTester(format) {
} }
function strip(html) { function strip(html) {
return domFromString(html).innerText; return domFromString(html)[0].innerText;
} }
discourseModule("Unit | Utility | formatter", function (hooks) { discourseModule("Unit | Utility | formatter", function (hooks) {
@ -121,12 +121,12 @@ discourseModule("Unit | Utility | formatter", function (hooks) {
); );
assert.strictEqual( assert.strictEqual(
domFromString(formatDays(0, { format: "medium" })).title, domFromString(formatDays(0, { format: "medium" }))[0].title,
longDate(new Date()) longDate(new Date())
); );
assert.ok( assert.ok(
domFromString(formatDays(0, { format: "medium" })).classList.contains( domFromString(formatDays(0, { format: "medium" }))[0].classList.contains(
"date" "date"
) )
); );
@ -226,12 +226,12 @@ discourseModule("Unit | Utility | formatter", function (hooks) {
test("autoUpdatingRelativeAge", function (assert) { test("autoUpdatingRelativeAge", function (assert) {
let d = moment().subtract(1, "day").toDate(); let d = moment().subtract(1, "day").toDate();
let elem = domFromString(autoUpdatingRelativeAge(d)); let elem = domFromString(autoUpdatingRelativeAge(d))[0];
assert.strictEqual(elem.dataset.format, "tiny"); assert.strictEqual(elem.dataset.format, "tiny");
assert.strictEqual(elem.dataset.time, d.getTime().toString()); assert.strictEqual(elem.dataset.time, d.getTime().toString());
assert.strictEqual(elem.title, ""); assert.strictEqual(elem.title, "");
elem = domFromString(autoUpdatingRelativeAge(d, { title: true })); elem = domFromString(autoUpdatingRelativeAge(d, { title: true }))[0];
assert.strictEqual(elem.title, longDate(d)); assert.strictEqual(elem.title, longDate(d));
elem = domFromString( elem = domFromString(
@ -240,14 +240,14 @@ discourseModule("Unit | Utility | formatter", function (hooks) {
title: true, title: true,
leaveAgo: true, leaveAgo: true,
}) })
); )[0];
assert.strictEqual(elem.dataset.format, "medium-with-ago"); assert.strictEqual(elem.dataset.format, "medium-with-ago");
assert.strictEqual(elem.dataset.time, d.getTime().toString()); assert.strictEqual(elem.dataset.time, d.getTime().toString());
assert.strictEqual(elem.title, longDate(d)); assert.strictEqual(elem.title, longDate(d));
assert.strictEqual(elem.innerHTML, "1 day ago"); assert.strictEqual(elem.innerHTML, "1 day ago");
elem = domFromString(autoUpdatingRelativeAge(d, { format: "medium" })); elem = domFromString(autoUpdatingRelativeAge(d, { format: "medium" }))[0];
assert.strictEqual(elem.dataset.format, "medium"); assert.strictEqual(elem.dataset.format, "medium");
assert.strictEqual(elem.dataset.time, d.getTime().toString()); assert.strictEqual(elem.dataset.time, d.getTime().toString());
assert.strictEqual(elem.title, ""); assert.strictEqual(elem.title, "");
@ -256,7 +256,7 @@ discourseModule("Unit | Utility | formatter", function (hooks) {
test("updateRelativeAge", function (assert) { test("updateRelativeAge", function (assert) {
let d = new Date(); let d = new Date();
let elem = domFromString(autoUpdatingRelativeAge(d)); let elem = domFromString(autoUpdatingRelativeAge(d))[0];
elem.dataset.time = d.getTime() - 2 * 60 * 1000; elem.dataset.time = d.getTime() - 2 * 60 * 1000;
updateRelativeAge(elem); updateRelativeAge(elem);
@ -266,7 +266,7 @@ discourseModule("Unit | Utility | formatter", function (hooks) {
d = new Date(); d = new Date();
elem = domFromString( elem = domFromString(
autoUpdatingRelativeAge(d, { format: "medium", leaveAgo: true }) autoUpdatingRelativeAge(d, { format: "medium", leaveAgo: true })
); )[0];
elem.dataset.time = d.getTime() - 2 * 60 * 1000; elem.dataset.time = d.getTime() - 2 * 60 * 1000;
updateRelativeAge(elem); updateRelativeAge(elem);

View File

@ -40,7 +40,7 @@ module("Unit | Utility | link-mentions", function () {
<span class="mention">@valid_group</span> <span class="mention">@valid_group</span>
<span class="mention">@mentionable_group</span> <span class="mention">@mentionable_group</span>
</div> </div>
`); `)[0];
await linkSeenMentions(root); await linkSeenMentions(root);
// Ember.Test.registerWaiter is not available here, so we are implementing // Ember.Test.registerWaiter is not available here, so we are implementing

View File

@ -76,7 +76,7 @@ function loadNext(ajax) {
}) })
.then( .then(
(template) => { (template) => {
const node = domFromString(template); const node = domFromString(template)[0];
setLocalCache(normalize(url), node); setLocalCache(normalize(url), node);
elem.replaceWith(node); elem.replaceWith(node);
applySquareGenericOnebox(node); applySquareGenericOnebox(node);