Skip to content

Commit 9030ba5

Browse files
committed
fix(pat-inject): Fix a problem with injections without a target which was introduced in 9.10.1-alpha.0.
1 parent 7506139 commit 9030ba5

File tree

2 files changed

+99
-9
lines changed

2 files changed

+99
-9
lines changed

src/pat/inject/inject.js

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ const inject = {
6464
// if the injection shall add a history entry and HTML5 pushState
6565
// is missing, then don't initialize the injection.
6666
log.warn("HTML5 pushState is missing, aborting");
67-
return;
67+
return $el;
6868
}
6969
$el.data("pat-inject", cfgs);
7070

@@ -350,6 +350,7 @@ const inject = {
350350
return false;
351351
}
352352
cfg.$target = this.createTarget(cfg.target);
353+
cfg.$created_target = cfg.$target;
353354
}
354355
return true;
355356
},
@@ -486,7 +487,7 @@ const inject = {
486487
// Update history
487488
this._update_history(cfg, trigger, title);
488489
// Post-injection
489-
this._afterInjection($el, $(source_nodes), cfg);
490+
this._afterInjection($el, cfg.$created_target || $(source_nodes), cfg);
490491
}
491492
},
492493

@@ -505,7 +506,7 @@ const inject = {
505506
if (title) {
506507
const title_el = document.querySelector("title");
507508
if (title_el) {
508-
this._inject(trigger, title, title_el, {
509+
this._inject(trigger, [title], title_el, {
509510
action: "element",
510511
});
511512
}
@@ -674,8 +675,8 @@ const inject = {
674675

675676
// clean up
676677
for (const cfg of cfgs) {
677-
if ("$injected" in cfg) {
678-
cfg.$injected.remove();
678+
if ("$created_target" in cfg) {
679+
cfg.$created_target.remove();
679680
}
680681
cfg.$target.removeClass(cfg.loadingClass);
681682
$el.removeClass(cfg.executingClass);
@@ -779,14 +780,14 @@ const inject = {
779780
}
780781
},
781782

782-
_inject(trigger, source, target, cfg) {
783+
_inject(trigger, source_nodes, target, cfg) {
783784
if (cfg.source === "none") {
784785
// Special case. Clear the target after ajax call.
785786
target.replaceWith("");
786787
return true;
787788
}
788-
if (source.length === 0) {
789-
log.warn("Aborting injection, source not found:", source);
789+
if (source_nodes.length === 0) {
790+
log.warn("Aborting injection, source not found:", source_nodes);
790791
$(trigger).trigger("pat-inject-missingSource", {
791792
url: cfg.url,
792793
selector: cfg.source,
@@ -816,7 +817,7 @@ const inject = {
816817
}[cfg.action];
817818

818819
// Inject the content HERE!
819-
target[method](...source);
820+
target[method](...source_nodes);
820821

821822
return true;
822823
},

src/pat/inject/inject.test.js

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1563,6 +1563,95 @@ describe("pat-inject", function () {
15631563
});
15641564
});
15651565
});
1566+
1567+
describe("9.3 - inject with not existing target element", function () {
1568+
let spy_ajax;
1569+
1570+
beforeEach(function () {
1571+
spy_ajax = jest.spyOn($, "ajax").mockImplementation(() => deferred);
1572+
});
1573+
1574+
afterEach(function () {
1575+
spy_ajax.mockRestore();
1576+
});
1577+
1578+
it("9.3.1 - Create non-existing target", async function () {
1579+
// Test a real-world scenario with modals where the target
1580+
// element does not exist and the source is implicitly defined
1581+
// via the href attribue.
1582+
// NOTE: pat-modal does the injecton part on it's own, so you
1583+
// normally use the `pat-modal` class and do not specify a
1584+
// target.
1585+
// For examples, see the pat-modal pattern.
1586+
1587+
document.body.innerHTML = `
1588+
<a class="pat-inject"
1589+
href="test.html#document-content"
1590+
data-pat-inject="target: #pat-modal">link</a>
1591+
`;
1592+
1593+
answer(`
1594+
<html>
1595+
<body>
1596+
<div id="document-content">
1597+
<dialog>
1598+
<h1>hello</h1>
1599+
</dialog>
1600+
</div>
1601+
</body>
1602+
</html>
1603+
`);
1604+
1605+
const inject = document.querySelector(".pat-inject");
1606+
1607+
pattern.init($(inject));
1608+
await utils.timeout(1); // wait a tick for async to settle.
1609+
1610+
inject.click();
1611+
1612+
await utils.timeout(1); // wait a tick for async to settle.
1613+
1614+
console.log(document.body.innerHTML);
1615+
const modal = document.querySelector("#pat-modal");
1616+
expect(modal).toBeTruthy();
1617+
expect(modal.innerHTML.replace(/\s/g, "")).toBe(
1618+
"<dialog><h1>hello</h1></dialog>"
1619+
);
1620+
});
1621+
1622+
it("9.3.2 - Does not create non-existing target without a target specifier", async function () {
1623+
document.body.innerHTML = `
1624+
<a class="pat-inject"
1625+
href="test.html#document-content">link</a>
1626+
`;
1627+
1628+
answer(`
1629+
<html>
1630+
<body>
1631+
<div id="document-content">
1632+
<dialog>
1633+
<h1>hello</h1>
1634+
</dialog>
1635+
</div>
1636+
</body>
1637+
</html>
1638+
`);
1639+
1640+
const inject = document.querySelector(".pat-inject");
1641+
1642+
pattern.init($(inject));
1643+
await utils.timeout(1); // wait a tick for async to settle.
1644+
1645+
inject.click();
1646+
1647+
await utils.timeout(1); // wait a tick for async to settle.
1648+
1649+
console.log(document.body.innerHTML);
1650+
const modal = document.querySelector("#pat-modal");
1651+
expect(modal).toBeFalsy();
1652+
});
1653+
});
1654+
15661655
});
15671656

15681657
describe("10 - Error handling", () => {

0 commit comments

Comments
 (0)