Skip to content

Commit 971199e

Browse files
authored
Merge pull request #790 from Patternslib/thet-parser
Rebase URLs in pattern options.
2 parents 05d0be5 + 4ae77ec commit 971199e

File tree

26 files changed

+443
-283
lines changed

26 files changed

+443
-283
lines changed

CHANGES.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@
5555
- pat tabs: When clicking on the ``extra-tabs`` element, toggle between ``open`` and ``closed`` classes to allow opening/closing an extra-tabs menu via CSS.
5656
- pat autofocus: Do not autofocus in iframes. Fixes: #761.
5757
- pat inject: Allow configurable error pages. Can be disabled by adding ``pat-inject-errorhandler.off`` to the URL's query string.
58+
- core utils: Add ``jqToNode`` to return a DOM node if a jQuery node was passed.
59+
- pat inject: Rebase URLs in pattern configuration attributes. This avoids URLs in pattern configuration to point to unreachable paths in the context where the result is injected into.
5860

5961
### Technical
6062

@@ -82,7 +84,8 @@
8284
Configure ``style_loader`` to insert CSS at the TOP of the html ``<head>``
8385
Provide a webpack-helpers module with a ``top_head_insert`` function which can be reused in depending projects.
8486
- Build infra: Switch the CI system to GitHub Actions and drop Travis CI.
85-
87+
- core base: Add the parser instance to pattern attributes if available.
88+
We can then reuse the parser from registered patterns. This is used in the ``_rebaseHTML`` method of pat-inject to URL-rebase the pattern configuration.
8689

8790
### Fixes
8891

src/core/base.js

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@ import Registry from "./registry";
1717
import logging from "./logging";
1818
import mockupParser from "./mockup-parser";
1919

20-
var log = logging.getLogger("Patternslib Base");
20+
const log = logging.getLogger("Patternslib Base");
2121

22-
var initBasePattern = function ($el, options, trigger) {
22+
const initBasePattern = function ($el, options, trigger) {
2323
if (!$el.jquery) {
2424
$el = $($el);
2525
}
26-
var name = this.prototype.name;
27-
var log = logging.getLogger("pat." + name);
28-
var pattern = $el.data("pattern-" + name);
26+
const name = this.prototype.name;
27+
const plog = logging.getLogger(`pat.${name}`);
28+
let pattern = $el.data(`pattern-${name}`);
2929
if (pattern === undefined && Registry.patterns[name]) {
3030
try {
3131
options =
@@ -34,14 +34,14 @@ var initBasePattern = function ($el, options, trigger) {
3434
: options;
3535
pattern = new Registry.patterns[name]($el, options, trigger);
3636
} catch (e) {
37-
log.error("Failed while initializing '" + name + "' pattern.", e);
37+
plog.error(`Failed while initializing ${name} pattern.`, e);
3838
}
39-
$el.data("pattern-" + name, pattern);
39+
$el.data(`pattern-${name}`, pattern);
4040
}
4141
return pattern;
4242
};
4343

44-
var Base = function ($el, options, trigger) {
44+
const Base = function ($el, options, trigger) {
4545
if (!$el.jquery) {
4646
$el = $($el);
4747
}
@@ -54,23 +54,23 @@ var Base = function ($el, options, trigger) {
5454

5555
Base.prototype = {
5656
constructor: Base,
57-
on: function (eventName, eventCallback) {
58-
this.$el.on(eventName + "." + this.name + ".patterns", eventCallback);
57+
on(eventName, eventCallback) {
58+
this.$el.on(`${eventName}.${this.name}.patterns`, eventCallback);
5959
},
60-
emit: function (eventName, args) {
60+
emit(eventName, args) {
6161
// args should be a list
6262
if (args === undefined) {
6363
args = [];
6464
}
65-
this.$el.trigger(eventName + "." + this.name + ".patterns", args);
65+
this.$el.trigger(`${eventName}.${this.name}.patterns`, args);
6666
},
6767
};
6868

6969
Base.extend = function (patternProps) {
7070
/* Helper function to correctly set up the prototype chain for new patterns.
7171
*/
72-
var parent = this;
73-
var child;
72+
const parent = this;
73+
let child;
7474

7575
// Check that the required configuration properties are given.
7676
if (!patternProps) {
@@ -97,6 +97,7 @@ Base.extend = function (patternProps) {
9797
child.init = initBasePattern;
9898
child.jquery_plugin = true;
9999
child.trigger = patternProps.trigger;
100+
child.parser = patternProps?.parser || null;
100101

101102
// Set the prototype chain to inherit from `parent`, without calling
102103
// `parent`'s constructor function.
@@ -120,10 +121,7 @@ Base.extend = function (patternProps) {
120121
);
121122
} else if (!patternProps.trigger) {
122123
log.warn(
123-
"The pattern '" +
124-
patternProps.name +
125-
"' does not " +
126-
"have a trigger attribute, it will not be registered."
124+
`The pattern ${patternProps.name} does not have a trigger attribute, it will not be registered.`
127125
);
128126
} else {
129127
Registry.register(child, patternProps.name);

src/core/dom.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ const find_parents = (el, selector) => {
5757
// This matches against all parents but not the element itself.
5858
// The order of elements is from the search starting point up to higher
5959
// DOM levels.
60-
let parent = el.parentNode?.closest(selector) || null;
60+
let parent =
61+
(el?.parentNode?.closest && el.parentNode.closest(selector)) || null;
6162
const ret = [];
6263
while (parent) {
6364
ret.push(parent);

src/core/dom.test.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,24 @@ describe("core.dom tests", () => {
173173
expect(res[0]).toEqual(document.querySelector(".level3")); // inner dom levels first // prettier-ignore
174174
expect(res[1]).toEqual(document.querySelector(".level1"));
175175

176+
done();
177+
});
178+
it("don't break with no element.", (done) => {
179+
const res = dom.find_parents(null, ".findme");
180+
expect(res.length).toEqual(0);
181+
182+
done();
183+
});
184+
it("don't break with DocumentFragment without a parent.", (done) => {
185+
const el = new DocumentFragment();
186+
el.innerHTML = `<div class="starthere"></div>`;
187+
console.log(el.parentNode);
188+
const res = dom.find_parents(
189+
el.querySelector(".starthere"),
190+
".findme"
191+
);
192+
expect(res.length).toEqual(0);
193+
176194
done();
177195
});
178196
});

src/core/mockup-parser.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import $ from "jquery";
22

33
var parser = {
4-
getOptions: function getOptions($el, patternName, options) {
4+
getOptions($el, patternName, options) {
55
/* This is the Mockup parser. An alternative parser for Patternslib
66
* patterns.
77
*
@@ -13,23 +13,23 @@ var parser = {
1313
options = options || {};
1414
// get options from parent element first, stop if element tag name is 'body'
1515
if ($el.length !== 0 && !$.nodeName($el[0], "body")) {
16-
options = getOptions($el.parent(), patternName, options);
16+
options = this.getOptions($el.parent(), patternName, options);
1717
}
1818
// collect all options from element
19-
var elOptions = {};
19+
let elOptions = {};
2020
if ($el.length !== 0) {
2121
elOptions = $el.data("pat-" + patternName);
2222
if (elOptions) {
2323
// parse options if string
2424
if (typeof elOptions === "string") {
25-
var tmpOptions = {};
25+
const tmpOptions = {};
2626
$.each(elOptions.split(";"), function (i, item) {
2727
item = item.split(":");
2828
item.reverse();
29-
var key = item.pop();
29+
let key = item.pop();
3030
key = key.replace(/^\s+|\s+$/g, ""); // trim
3131
item.reverse();
32-
var value = item.join(":");
32+
let value = item.join(":");
3333
value = value.replace(/^\s+|\s+$/g, ""); // trim
3434
tmpOptions[key] = value;
3535
});

0 commit comments

Comments
 (0)