forked from bpmn-io/moddle
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathproperties.js
More file actions
131 lines (105 loc) · 2.93 KB
/
properties.js
File metadata and controls
131 lines (105 loc) · 2.93 KB
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
/**
* A utility that gets and sets properties of model elements.
*
* @param {Model} model
*/
export default function Properties(model) {
this.model = model;
}
/**
* Sets a named property on the target element.
* If the value is undefined, the property gets deleted.
*
* @param {Object} target
* @param {String} name
* @param {Object} value
*/
Properties.prototype.set = function(target, name, value) {
var property = this.model.getPropertyDescriptor(target, name);
var propertyName = getPropertyName(target, name, property);
if (isUndefined(value)) {
// unset the property, if the specified value is undefined;
// delete from $attrs (for extensions) or the target itself
if (property) {
delete target[propertyName];
} else {
delete target.$attrs[name];
}
} else {
// set the property, defining well defined properties on the fly or simply
// updating them in target.$attrs (for extensions)
if (property) {
if (propertyName in target) {
target[propertyName] = value;
} else {
defineProperty(target, propertyName, property, value);
}
} else {
target.$attrs[name] = value;
}
}
};
/**
* Returns the named property of the given element
*
* @param {Object} target
* @param {String} name
*
* @return {Object}
*/
Properties.prototype.get = function(target, name) {
var property = this.model.getPropertyDescriptor(target, name);
var propertyName = getPropertyName(target, name, property);
if (!property) {
return target.$attrs[name];
}
// check if access to collection property and lazily initialize it
if (!target[propertyName] && property.isMany) {
defineProperty(target, propertyName, property, []);
}
return target[propertyName];
};
/**
* Define a property on the target element
*
* @param {Object} target
* @param {String} name
* @param {Object} options
*/
Properties.prototype.define = function(target, name, options) {
Object.defineProperty(target, name, options);
};
/**
* Define the descriptor for an element
*/
Properties.prototype.defineDescriptor = function(target, descriptor) {
this.define(target, '$descriptor', { value: descriptor });
};
/**
* Define the model for an element
*/
Properties.prototype.defineModel = function(target, model) {
this.define(target, '$model', { value: model });
};
function isUndefined(val) {
return typeof val === 'undefined';
}
function getPropertyName(target, name, descriptor) {
if (!target || !name || !descriptor)
return undefined;
var propertyName = descriptor.name;
if (name.includes(':')) {
var parts = name.split(':');
if (parts[0] !== target.$descriptor.ns.prefix)
propertyName = descriptor.ns.name;
}
return propertyName;
}
function defineProperty(target, name, property, value) {
Object.defineProperty(target, name, {
enumerable: !property.isReference,
writable: true,
value: value,
configurable: true
});
}