-
Notifications
You must be signed in to change notification settings - Fork 42
/
Copy pathbase.js
144 lines (126 loc) · 4.65 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
/**
* 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 "regenerator-runtime/runtime"; // needed for ``await`` support
import $ from "jquery";
import Registry, { PATTERN_INSTANCE_REGISTRY } from "./registry";
import logging from "./logging";
import mockupParser from "./mockup-parser";
import utils from "./utils";
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 {
$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.jquery) {
$el = $($el);
}
this.$el = $el;
this.el = $el[0];
this.options = $.extend(true, {}, this.defaults || {}, options || {});
await this.init($el, options, trigger);
this.id = utils.unique_id(); // Generate a unique id
// Store pattern instance on element
this.$el.data(`pattern-${this.name}`, this);
this.el[`pattern-${this.name}`] = this;
// Add Pattern instance to PATTERN_INSTANCE_REGISTRY
PATTERN_INSTANCE_REGISTRY.push(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 {
Registry.register(child, patternProps.name);
}
return child;
};
export default Base;