forked from reactive-elements/reactive-elements
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathreactive-elements.js
More file actions
125 lines (106 loc) · 4.69 KB
/
Copy pathreactive-elements.js
File metadata and controls
125 lines (106 loc) · 4.69 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
React = typeof React === 'object' ? React : require('react');
(function (w) {
var PROPERTY_DELIMITER_CHARACTERS = [':', '-', '_'];
if (document.registerElement || document.register) {
var registrationFunction = (document.registerElement || document.register).bind(document);
}
var registerReact = function (elementName, reactClass) {
var elementPrototype = Object.create(HTMLElement.prototype);
elementPrototype.createdCallback = function () {
this._content = utils.getContentNodes(this);
var reactElement = React.createElement(reactClass, utils.getAllProperties(this, this.attributes));
//Since React v0.12 API was changed, so need a check for current API
this.reactiveElement = React.render(reactElement, this);
utils.extend(this, this.reactiveElement);
utils.getterSetter(this, 'props', function () {
return this.reactiveElement.props;
}, function (value) {
this.reactiveElement.setProps(value);
});
};
elementPrototype.attributeChangedCallback = function (name, oldValue, newValue) {
this.reactiveElement.props = utils.getAllProperties(this, this.attributes);
this.reactiveElement.forceUpdate();
if (this.reactiveElement.attributeChanged !== undefined) {
this.reactiveElement.attributeChanged.bind(this)(name, oldValue, newValue);
}
}
registrationFunction(elementName, {
prototype: elementPrototype
});
};
var utils = {
extend: function (extandable, extending) {
for (var i in extending) {
if (!(i in extandable)) {
if (typeof extending[i] === 'function') {
extandable[i] = extending[i].bind(extending);
} else {
extandable[i] = extending[i];
}
}
}
},
getContentNodes: function (el) {
var fragment = document.createElement('content');
while(el.childNodes.length) {
fragment.appendChild(el.childNodes[0]);
}
return fragment;
},
getAllProperties: function (el, attributes) {
var result = {};
for (var i = 0; i < attributes.length; i++) {
var attribute = attributes[i];
var propertyName = utils.attributeNameToPropertyName(attribute.name);
result[propertyName] = utils.parseAttributeValue(attributes[i].value);
}
result._content = el._content;
return result;
},
attributeNameToPropertyName: function (attributeName) {
return attributeName
.replace(/^x\-|^data\-/i, '')
.replace(/\W+(.)/g, function(x, chr) {
return chr.toUpperCase();
});
},
parseAttributeValue: function (value) {
var pointerRegexp = /\{.*?\}/g,
jsonRegexp = /\{{.*?\}}/g,
jsonArrayRegexp = /\{{.*?\}}/g;
var pointerMatches = value.match(pointerRegexp),
jsonMatches = value.match(jsonRegexp) || value.match(jsonArrayRegexp);
if (jsonMatches && jsonMatches.length > 0) {
jsonMatches[0] = jsonMatches[0].substring(1, jsonMatches[0].length - 1).replace(/'/g, '"');
value = JSON.parse(jsonMatches[0]);
} else if (pointerMatches && pointerMatches.length > 0) {
value = eval(pointerMatches[0].replace('{', '').replace('}', ''));
}
return value;
},
getterSetter: function (variableParent, variableName, getterFunction, setterFunction) {
if (Object.defineProperty) {
Object.defineProperty(variableParent, variableName, {
get: getterFunction,
set: setterFunction
});
}
else if (document.__defineGetter__) {
variableParent.__defineGetter__(variableName, getterFunction);
variableParent.__defineSetter__(variableName, setterFunction);
}
variableParent["get" + variableName] = getterFunction;
variableParent["set" + variableName] = setterFunction;
}
};
window.ReactiveElements = {};
window.ReactiveElements.utils = utils;
document.registerReact = registerReact;
if (typeof module === 'object' && module.exports) {
module.exports = registerReact;
}
if (w.xtag !== undefined) {
w.xtag.registerReact = registerReact;
}
})(window);