Skip to content

Commit 97efc57

Browse files
committed
pat-inject: Minor code optimization.
1 parent ef6fc21 commit 97efc57

File tree

1 file changed

+62
-52
lines changed

1 file changed

+62
-52
lines changed

src/pat/inject/inject.js

Lines changed: 62 additions & 52 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,30 @@ 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_ + "']"
145-
);
146-
if (still_there.length == 0) return false;
147+
const still_there = document.querySelector(`[data-pat-inject-uid="${uid_}"]`);
148+
if (! still_there) {
149+
return false;
150+
}
147151

148152
$el.data("pat-inject-autoloaded", true);
149-
this.onTrigger({ currentTarget: $el[0] });
153+
this.onTrigger({ currentTarget: el });
150154
return true;
151155
};
152156
window.setTimeout(
@@ -164,7 +168,7 @@ const inject = {
164168
}
165169
}
166170

167-
log.debug("initialised:", $el);
171+
log.debug("initialised:", el);
168172
return $el;
169173
},
170174

@@ -183,10 +187,11 @@ const inject = {
183187
// We want an AJAX request instead.
184188
e.preventDefault && e.preventDefault();
185189

186-
const $el = $(e.currentTarget);
190+
const el = e.currentTarget;
191+
const $el = $(el);
187192
let cfgs = $el.data("pat-inject");
188-
if ($el[0].tagName === "FORM" && e.type === "submit") {
189-
const form = $el[0];
193+
if (el.tagName === "FORM" && e.type === "submit") {
194+
const form = el;
190195
const submitter = e.submitter;
191196

192197
// Do not submit invalid forms, if validation is active.
@@ -239,19 +244,20 @@ const inject = {
239244
this.execute(cfgs, $el);
240245
},
241246

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

245-
const cfgs = parser.parse($el, opts, true);
251+
const cfgs = parser.parse($el, options, true);
246252
cfgs.forEach((cfg) => {
247253
cfg.$context = $el;
248-
// opts and cfg have priority, fall back to href/action
254+
// options and cfg have priority, fall back to href/action
249255
cfg.url =
250-
opts.url ||
256+
options.url ||
251257
cfg.url ||
252-
$el.attr("href") ||
253-
$el.attr("action") ||
254-
$el.parents("form").attr("action") ||
258+
el?.getAttribute("href") ||
259+
el?.getAttribute("action") ||
260+
el?.closest("form")?.getAttribute("action") ||
255261
"";
256262

257263
// separate selector from url
@@ -431,8 +437,8 @@ const inject = {
431437
createTarget(selector) {
432438
/* create a target that matches the selector
433439
*
434-
* XXX: so far we only support #target and create a div with
435-
* that id appended to the body.
440+
* Note: so far we only support #target and create a div with that id
441+
* appended to the body.
436442
*/
437443
if (selector.slice(0, 1) !== "#") {
438444
log.error("only id supported for non-existing target");
@@ -489,6 +495,7 @@ const inject = {
489495
/* Set a class on the injected elements and fire the
490496
* patterns-injected event.
491497
*/
498+
const el = utils.jqToNode($el);
492499
$injected
493500
.filter((idx, el_) => {
494501
return el_.nodeType !== TEXT_NODE;
@@ -501,14 +508,14 @@ const inject = {
501508
// The event handler should check whether the
502509
// injected element and the triggered element are
503510
// the same.
504-
$injected.parent().trigger("patterns-injected", [cfg, $el[0], $injected[0]]);
511+
$injected.parent().trigger("patterns-injected", [cfg, el, $injected[0]]);
505512
} else {
506513
$injected.each((idx, el_) => {
507514
// patterns-injected event will be triggered for each injected (non-text) element.
508515
if (el_.nodeType !== TEXT_NODE) {
509516
$(el_)
510517
.addClass(cfg["class"])
511-
.trigger("patterns-injected", [cfg, $el[0], el_]);
518+
.trigger("patterns-injected", [cfg, el, el_]);
512519
}
513520
});
514521
}
@@ -534,7 +541,7 @@ const inject = {
534541
}
535542
}
536543

537-
$el[0].dispatchEvent(
544+
el.dispatchEvent(
538545
new Event("pat-inject-success", { bubbles: true, cancelable: true })
539546
);
540547
},
@@ -567,7 +574,7 @@ const inject = {
567574
}
568575
cfgs.forEach((cfg, idx1) => {
569576
const perform_inject = () => {
570-
if (cfg.target !== "none")
577+
if (cfg.target !== "none") {
571578
cfg.$target.each((idx2, target) => {
572579
this._performInjection(
573580
target,
@@ -578,6 +585,7 @@ const inject = {
578585
title
579586
);
580587
});
588+
}
581589
};
582590
if (cfg.processDelay) {
583591
setTimeout(() => perform_inject(), cfg.processDelay);
@@ -674,6 +682,7 @@ const inject = {
674682
* Either by making an ajax request or by spoofing an ajax
675683
* request when the content is readily available in the current page.
676684
*/
685+
const el = utils.jqToNode($el);
677686
// get a kinda deep copy, we scribble on it
678687
cfgs = cfgs.map((cfg) => $.extend({}, cfg));
679688
if (!this.verifyConfig(cfgs)) {
@@ -691,7 +700,7 @@ const inject = {
691700
for (const cfg of cfgs) {
692701
// Add a execute class on the pat-inject element.
693702
if (cfg?.executingClass) {
694-
$el[0].classList.add(cfg.executingClass);
703+
el.classList.add(cfg.executingClass);
695704
}
696705
// Add a loading class to the target.
697706
// Can be used for loading-spinners.
@@ -707,12 +716,12 @@ const inject = {
707716
// is called before this one, even for non-async local injects.
708717
await utils.timeout(1);
709718
// Remove the close-panel event listener.
710-
events.remove_event_listener($el[0], "pat-inject--close-panel");
719+
events.remove_event_listener(el, "pat-inject--close-panel");
711720
// Only close the panel if a close-panel event was catched previously.
712721
if (do_close_panel) {
713722
do_close_panel = false;
714723
// Re-trigger close-panel event if it was caught while injection was in progress.
715-
$el[0].dispatchEvent(
724+
el.dispatchEvent(
716725
new Event("close-panel", { bubbles: true, cancelable: true })
717726
);
718727
}
@@ -725,7 +734,7 @@ const inject = {
725734
// Prevent closing the panel while injection is in progress.
726735
let do_close_panel = false;
727736
events.add_event_listener(
728-
$el[0],
737+
el,
729738
"close-panel",
730739
"pat-inject--close-panel",
731740
(e) => {
@@ -964,7 +973,7 @@ const inject = {
964973
return false;
965974
}
966975

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

969978
// delay: default is 200ms to allow scrolling over and past autoload-visible elements without loading them.
970979
const delay = cfgs[0].delay || 200;
@@ -1011,18 +1020,20 @@ const inject = {
10111020
},
10121021

10131022
_initIdleTrigger($el, delay) {
1014-
// XXX TODO: handle item removed from DOM
1023+
// TODO: handle item removed from DOM
10151024
const timeout = parseInt(delay, 10);
10161025
let timer;
10171026

1027+
const el = utils.jqToNode($el);
1028+
10181029
const onTimeout = () => {
1019-
this.onTrigger({ currentTarget: $el[0] });
1030+
this.onTrigger({ currentTarget: el });
10201031
unsub();
10211032
clearTimeout(timer);
10221033
};
10231034

10241035
const onInteraction = utils.debounce(() => {
1025-
if (!document.body.contains($el[0])) {
1036+
if (!document.body.contains(el)) {
10261037
unsub();
10271038
return;
10281039
}
@@ -1052,7 +1063,6 @@ const inject = {
10521063
);
10531064
},
10541065

1055-
// XXX: simple so far to see what the team thinks of the idea
10561066
registerTypeHandler(type, handler) {
10571067
this.handlers[type] = handler;
10581068
},
@@ -1083,7 +1093,7 @@ $(document).on("patterns-injected.inject", async (ev, cfg, trigger, injected) =>
10831093
* Remove the "loading-class" classes from all injection targets and
10841094
* then scan the injected content for new patterns.
10851095
*/
1086-
if (cfg && cfg.skipPatInjectHandler) {
1096+
if (cfg?.skipPatInjectHandler) {
10871097
// Allow skipping this handler but still have other handlers in other
10881098
// patterns listen to ``patterns-injected``.
10891099
return;

0 commit comments

Comments
 (0)