-
Notifications
You must be signed in to change notification settings - Fork 42
/
Copy pathbase.js
147 lines (131 loc) · 4.81 KB
/
base.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/**
* A Base pattern for creating scoped patterns. It's similar to Backbone's
* Model class. The advantage of this approach is that each instance of a
* pattern has its own local scope (closure).
*
* A new instance is created for each DOM element on which a pattern applies.
*
* You can assign values, such as $el, to `this` for an instance and they
* will remain unique to that instance.
*
* Older Patternslib patterns on the other hand have a single global scope for
* all DOM elements.
*/
import $ from "jquery";
import Registry from "./registry";
import logging from "./logging";
import mockupParser from "./mockup-parser";
const log = logging.getLogger("Patternslib Base");
const initBasePattern = function ($el, options, trigger) {
if (!$el.jquery) {
$el = $($el);
}
const name = this.prototype.name;
const plog = logging.getLogger(`pat.${name}`);
let pattern = $el.data(`pattern-${name}`);
if (pattern === undefined && Registry.patterns[name]) {
try {
// Immediately set the pattern instance to the temporary value
// ``initializing`` before the async Base constructor is setting
// the value later.
// This prevents re-init the pattern on this element on multiple
// initialization calls..
$el.data(`pattern-${name}`, "initializing");
options =
this.prototype.parser === "mockup"
? mockupParser.getOptions($el, name, options)
: options;
pattern = new Registry.patterns[name]($el, options, trigger);
} catch (e) {
plog.error(`Failed while initializing ${name} pattern.`, e);
}
}
return pattern;
};
const Base = async function ($el, options, trigger) {
if (!$el) {
log.warn("No element given to pattern.");
return;
}
if (!$el.jquery) {
$el = $($el);
}
this.$el = $el;
this.el = $el[0];
this.options = $.extend(true, {}, this.defaults || {}, options || {});
await this.init($el, options, trigger);
// Store pattern instance on element
this.$el.data(`pattern-${this.name}`, this);
this.el[`pattern-${this.name}`] = this;
this.emit("init");
};
Base.prototype = {
constructor: Base,
on(eventName, eventCallback) {
this.$el.on(`${eventName}.${this.name}.patterns`, eventCallback);
},
one(eventName, eventCallback) {
this.$el.one(`${eventName}.${this.name}.patterns`, eventCallback);
},
emit(eventName, args) {
// args should be a list
if (args === undefined) {
args = [];
}
this.$el.trigger(`${eventName}.${this.name}.patterns`, args);
},
};
Base.extend = function (patternProps) {
/* Helper function to correctly set up the prototype chain for new patterns.
*/
const parent = this;
let child;
// Check that the required configuration properties are given.
if (!patternProps) {
throw new Error(
"Pattern configuration properties required when calling Base.extend"
);
}
// The constructor function for the new subclass is either defined by you
// (the "constructor" property in your `extend` definition), or defaulted
// by us to simply call the parent's constructor.
if (Object.hasOwnProperty.call(patternProps, "constructor")) {
child = patternProps.constructor;
} else {
child = function () {
parent.apply(this, arguments);
};
}
// Allow patterns to be extended indefinitely
child.extend = Base.extend;
// Static properties required by the Patternslib registry
child.init = initBasePattern;
child.jquery_plugin = true;
child.trigger = patternProps.trigger;
child.parser = patternProps?.parser || null;
// Set the prototype chain to inherit from `parent`, without calling
// `parent`'s constructor function.
var Surrogate = function () {
this.constructor = child;
};
Surrogate.prototype = parent.prototype;
child.prototype = new Surrogate();
// Add pattern's configuration properties (instance properties) to the subclass,
$.extend(true, child.prototype, patternProps);
// Set a convenience property in case the parent's prototype is needed
// later.
child.__super__ = parent.prototype;
// Register the pattern in the Patternslib registry.
if (!patternProps.name) {
log.warn("This pattern without a name attribute will not be registered!");
} else if (!patternProps.trigger) {
log.warn(
`The pattern ${patternProps.name} does not have a trigger attribute, it will not be registered.`
);
} else if (patternProps.autoregister !== false) {
Registry.register(child, patternProps.name);
}
return child;
};
export default Base;
export { Base };