Skip to content

Commit 5c3c1aa

Browse files
committed
pat-inject: Minor code optimization.
1 parent 3369d3a commit 5c3c1aa

File tree

1 file changed

+67
-60
lines changed

1 file changed

+67
-60
lines changed

src/pat/inject/inject.js

Lines changed: 67 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ parser.addArgument("class"); // Add a class to the injected content.
3838
parser.addArgument("history", "none", ["none", "record"]);
3939
parser.addArgument("push-marker");
4040
parser.addArgument("scroll");
41-
// XXX: this should not be here but the parser would bail on
42-
// unknown parameters and expand/collapsible need to pass the url
43-
// to us
41+
42+
// Note: this should not be here but the parser would bail on unknown
43+
// parameters and expand/collapsible need to pass the url to us.
4444
parser.addArgument("url");
4545

4646
const inject = {
@@ -56,12 +56,15 @@ const inject = {
5656
// from pat-inject. Waiting a tick in pat-inject solves this -
5757
// pat-validation's event handlers are initialized first.
5858
await utils.timeout(1);
59+
60+
const el = utils.jqToNode($el);
61+
5962
const cfgs = this.extractConfig($el, opts);
6063
if (cfgs.some((e) => e.history === "record") && !("pushState" in history)) {
6164
// if the injection shall add a history entry and HTML5 pushState
6265
// is missing, then don't initialize the injection.
6366
log.warn("HTML5 pushState is missing, aborting");
64-
return $el;
67+
return;
6568
}
6669
$el.data("pat-inject", cfgs);
6770

@@ -70,26 +73,27 @@ const inject = {
7073
// exists in the page, we do not activate the injection
7174
// but instead just change the anchors href.
7275

73-
// XXX: This is used in only one project for linked
74-
// fullcalendars, it's sanity is wonky and we should
75-
// probably solve it differently.
76-
if ($el.is("a") && $(cfgs[0].nextHref).length > 0) {
76+
// Note: This is used in only one project for linked fullcalendars,
77+
// it's sanity is wonky and we should probably solve it differently.
78+
if (el.nodeName === "A" && $(cfgs[0].nextHref).length > 0) {
7779
log.debug(
7880
"Skipping as next href is anchor, which already exists",
7981
cfgs[0].nextHref
8082
);
81-
// XXX: reconsider how the injection enters exhausted state
82-
return $el.attr({
83-
href: (window.location.href.split("#")[0] || "") + cfgs[0].nextHref,
84-
});
83+
// TODO: reconsider how the injection enters exhausted state
84+
el.setAttribute(
85+
"href",
86+
(window.location.href.split("#")[0] || "") + cfgs[0].nextHref
87+
);
88+
return $el;
8589
}
8690
}
8791
if (cfgs[0].pushMarker) {
8892
$("body").on("push", (event, data) => {
8993
log.debug("received push message: " + data);
9094
if (data == cfgs[0].pushMarker) {
9195
log.debug("re-injecting " + data);
92-
this.onTrigger({ currentTarget: $el[0] });
96+
this.onTrigger({ currentTarget: el });
9397
}
9498
});
9599
}
@@ -104,10 +108,10 @@ const inject = {
104108
}
105109
});
106110
// setup event handlers
107-
if ($el[0]?.tagName === "FORM") {
108-
log.debug("Initializing form with injection on", $el[0]);
111+
if (el?.tagName === "FORM") {
112+
log.debug("Initializing form with injection on", el);
109113
events.add_event_listener(
110-
$el[0],
114+
el,
111115
"submit",
112116
"pat-inject--form-submit",
113117
(e) => {
@@ -123,30 +127,32 @@ const inject = {
123127
this.onTrigger(e);
124128
}
125129
);
126-
} else if ($el.is(".pat-subform")) {
130+
} else if (el?.matches(".pat-subform")) {
127131
log.debug("Initializing subform with injection");
128132
} else {
129133
$el.on("click.pat-inject", this.onTrigger.bind(this));
130134
}
131135
break;
132136
case "autoload":
133137
if (!cfgs[0].delay) {
134-
this.onTrigger({ currentTarget: $el[0] });
138+
this.onTrigger({ currentTarget: el });
135139
} else {
136140
// generate UID
137141
const uid = Math.random().toString(36);
138-
$el.attr("data-pat-inject-uid", uid);
142+
el.setAttribute("data-pat-inject-uid", uid);
139143

140144
// function to trigger the autoload and mark as triggered
141145
const delayed_trigger = (uid_) => {
142146
// Check if the element has been removed from the dom
143-
const still_there = $(
144-
"[data-pat-inject-uid='" + uid_ + "']"
147+
const still_there = document.querySelector(
148+
`[data-pat-inject-uid="${uid_}"]`
145149
);
146-
if (still_there.length == 0) return false;
150+
if (!still_there) {
151+
return false;
152+
}
147153

148154
$el.data("pat-inject-autoloaded", true);
149-
this.onTrigger({ currentTarget: $el[0] });
155+
this.onTrigger({ currentTarget: el });
150156
return true;
151157
};
152158
window.setTimeout(
@@ -164,7 +170,7 @@ const inject = {
164170
}
165171
}
166172

167-
log.debug("initialised:", $el);
173+
log.debug("initialised:", el);
168174
return $el;
169175
},
170176

@@ -183,10 +189,11 @@ const inject = {
183189
// We want an AJAX request instead.
184190
e.preventDefault && e.preventDefault();
185191

186-
const $el = $(e.currentTarget);
192+
const el = e.currentTarget;
193+
const $el = $(el);
187194
let cfgs = $el.data("pat-inject");
188-
if ($el[0].tagName === "FORM" && e.type === "submit") {
189-
const form = $el[0];
195+
if (el.tagName === "FORM" && e.type === "submit") {
196+
const form = el;
190197
const submitter = e.submitter;
191198

192199
// Do not submit invalid forms, if validation is active.
@@ -239,19 +246,20 @@ const inject = {
239246
this.execute(cfgs, $el);
240247
},
241248

242-
extractConfig($el, opts) {
243-
opts = $.extend({}, opts);
249+
extractConfig($el, options = {}) {
250+
const el = utils.jqToNode($el);
251+
options = Object.assign({}, options); // copy
244252

245-
const cfgs = parser.parse($el, opts, true);
253+
const cfgs = parser.parse($el, options, true);
246254
cfgs.forEach((cfg) => {
247255
cfg.$context = $el;
248-
// opts and cfg have priority, fall back to href/action
256+
// options and cfg have priority, fall back to href/action
249257
cfg.url =
250-
opts.url ||
258+
options.url ||
251259
cfg.url ||
252-
$el.attr("href") ||
253-
$el.attr("action") ||
254-
$el.parents("form").attr("action") ||
260+
el?.getAttribute("href") ||
261+
el?.getAttribute("action") ||
262+
el?.closest("form")?.getAttribute("action") ||
255263
"";
256264

257265
// separate selector from url
@@ -431,8 +439,8 @@ const inject = {
431439
createTarget(selector) {
432440
/* create a target that matches the selector
433441
*
434-
* XXX: so far we only support #target and create a div with
435-
* that id appended to the body.
442+
* Note: so far we only support #target and create a div with that id
443+
* appended to the body.
436444
*/
437445
if (selector.slice(0, 1) !== "#") {
438446
log.error("only id supported for non-existing target");
@@ -489,6 +497,7 @@ const inject = {
489497
/* Set a class on the injected elements and fire the
490498
* patterns-injected event.
491499
*/
500+
const el = utils.jqToNode($el);
492501
$injected
493502
.filter((idx, el_) => {
494503
return el_.nodeType !== TEXT_NODE;
@@ -501,14 +510,14 @@ const inject = {
501510
// The event handler should check whether the
502511
// injected element and the triggered element are
503512
// the same.
504-
$injected.parent().trigger("patterns-injected", [cfg, $el[0], $injected[0]]);
513+
$injected.parent().trigger("patterns-injected", [cfg, el, $injected[0]]);
505514
} else {
506515
$injected.each((idx, el_) => {
507516
// patterns-injected event will be triggered for each injected (non-text) element.
508517
if (el_.nodeType !== TEXT_NODE) {
509518
$(el_)
510519
.addClass(cfg["class"])
511-
.trigger("patterns-injected", [cfg, $el[0], el_]);
520+
.trigger("patterns-injected", [cfg, el, el_]);
512521
}
513522
});
514523
}
@@ -534,7 +543,7 @@ const inject = {
534543
}
535544
}
536545

537-
$el[0].dispatchEvent(
546+
el.dispatchEvent(
538547
new Event("pat-inject-success", { bubbles: true, cancelable: true })
539548
);
540549
},
@@ -567,7 +576,7 @@ const inject = {
567576
}
568577
cfgs.forEach((cfg, idx1) => {
569578
const perform_inject = () => {
570-
if (cfg.target !== "none")
579+
if (cfg.target !== "none") {
571580
cfg.$target.each((idx2, target) => {
572581
this._performInjection(
573582
target,
@@ -578,6 +587,7 @@ const inject = {
578587
title
579588
);
580589
});
590+
}
581591
};
582592
if (cfg.processDelay) {
583593
setTimeout(() => perform_inject(), cfg.processDelay);
@@ -674,6 +684,7 @@ const inject = {
674684
* Either by making an ajax request or by spoofing an ajax
675685
* request when the content is readily available in the current page.
676686
*/
687+
const el = utils.jqToNode($el);
677688
// get a kinda deep copy, we scribble on it
678689
cfgs = cfgs.map((cfg) => $.extend({}, cfg));
679690
if (!this.verifyConfig(cfgs)) {
@@ -691,7 +702,7 @@ const inject = {
691702
for (const cfg of cfgs) {
692703
// Add a execute class on the pat-inject element.
693704
if (cfg?.executingClass) {
694-
$el[0].classList.add(cfg.executingClass);
705+
el.classList.add(cfg.executingClass);
695706
}
696707
// Add a loading class to the target.
697708
// Can be used for loading-spinners.
@@ -707,12 +718,12 @@ const inject = {
707718
// is called before this one, even for non-async local injects.
708719
await utils.timeout(1);
709720
// Remove the close-panel event listener.
710-
events.remove_event_listener($el[0], "pat-inject--close-panel");
721+
events.remove_event_listener(el, "pat-inject--close-panel");
711722
// Only close the panel if a close-panel event was catched previously.
712723
if (do_close_panel) {
713724
do_close_panel = false;
714725
// Re-trigger close-panel event if it was caught while injection was in progress.
715-
$el[0].dispatchEvent(
726+
el.dispatchEvent(
716727
new Event("close-panel", { bubbles: true, cancelable: true })
717728
);
718729
}
@@ -724,16 +735,11 @@ const inject = {
724735

725736
// Prevent closing the panel while injection is in progress.
726737
let do_close_panel = false;
727-
events.add_event_listener(
728-
$el[0],
729-
"close-panel",
730-
"pat-inject--close-panel",
731-
(e) => {
732-
e.stopPropagation();
733-
e.stopImmediatePropagation();
734-
do_close_panel = true;
735-
}
736-
);
738+
events.add_event_listener(el, "close-panel", "pat-inject--close-panel", (e) => {
739+
e.stopPropagation();
740+
e.stopImmediatePropagation();
741+
do_close_panel = true;
742+
});
737743

738744
if (cfgs[0].url.length) {
739745
ajax.request($el, {
@@ -964,7 +970,7 @@ const inject = {
964970
return false;
965971
}
966972

967-
const el = $el[0];
973+
const el = utils.jqToNode($el);
968974

969975
// delay: default is 200ms to allow scrolling over and past autoload-visible elements without loading them.
970976
const delay = cfgs[0].delay || 200;
@@ -1011,18 +1017,20 @@ const inject = {
10111017
},
10121018

10131019
_initIdleTrigger($el, delay) {
1014-
// XXX TODO: handle item removed from DOM
1020+
// TODO: handle item removed from DOM
10151021
const timeout = parseInt(delay, 10);
10161022
let timer;
10171023

1024+
const el = utils.jqToNode($el);
1025+
10181026
const onTimeout = () => {
1019-
this.onTrigger({ currentTarget: $el[0] });
1027+
this.onTrigger({ currentTarget: el });
10201028
unsub();
10211029
clearTimeout(timer);
10221030
};
10231031

10241032
const onInteraction = utils.debounce(() => {
1025-
if (!document.body.contains($el[0])) {
1033+
if (!document.body.contains(el)) {
10261034
unsub();
10271035
return;
10281036
}
@@ -1052,7 +1060,6 @@ const inject = {
10521060
);
10531061
},
10541062

1055-
// XXX: simple so far to see what the team thinks of the idea
10561063
registerTypeHandler(type, handler) {
10571064
this.handlers[type] = handler;
10581065
},
@@ -1083,7 +1090,7 @@ $(document).on("patterns-injected.inject", async (ev, cfg, trigger, injected) =>
10831090
* Remove the "loading-class" classes from all injection targets and
10841091
* then scan the injected content for new patterns.
10851092
*/
1086-
if (cfg && cfg.skipPatInjectHandler) {
1093+
if (cfg?.skipPatInjectHandler) {
10871094
// Allow skipping this handler but still have other handlers in other
10881095
// patterns listen to ``patterns-injected``.
10891096
return;

0 commit comments

Comments
 (0)