1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | 'use strict';
|
7 |
|
8 | var isFunction = (function (value) {
|
9 | return typeof value === 'function';
|
10 | });
|
11 |
|
12 | var isNumeric = (function (value) {
|
13 | return !isNaN(value - parseFloat(value));
|
14 | });
|
15 |
|
16 | var isObject = (function (value) {
|
17 | return value && typeof value === 'object';
|
18 | });
|
19 |
|
20 | var cache = Object.create(null);
|
21 | var upperCaseFirst = (function (str) {
|
22 | if (!(str in cache)) {
|
23 | cache[str] = str.charAt(0).toUpperCase() + str.slice(1);
|
24 | }
|
25 |
|
26 | return cache[str];
|
27 | });
|
28 |
|
29 | var defaultModel = {
|
30 | prop: 'value',
|
31 | event: 'input'
|
32 | };
|
33 | var index = {
|
34 | beforeCreate: function beforeCreate() {
|
35 | if (this.__MessengerBeforeCreate__) return;
|
36 | this.__MessengerBeforeCreate__ = true;
|
37 | var options = this.$options;
|
38 | if (!options.localDataKeys) options.localDataKeys = [];
|
39 | if (!options.methods) options.methods = {};
|
40 | if (!options.watch) options.watch = {};
|
41 | var model = options.model || defaultModel;
|
42 | var props = options.props || {};
|
43 |
|
44 | var _arr = Object.keys(props);
|
45 |
|
46 | var _loop = function _loop() {
|
47 | var prop = _arr[_i];
|
48 | var descriptor = props[prop];
|
49 |
|
50 | if (Array.isArray(descriptor.enum)) {
|
51 | var nextValidator = descriptor.validator;
|
52 |
|
53 | descriptor.validator = function (value) {
|
54 | return descriptor.enum.indexOf(value) >= 0 && (nextValidator ? nextValidator.apply(this, arguments) : true);
|
55 | };
|
56 |
|
57 | if (!('default' in descriptor)) {
|
58 | descriptor.default = descriptor.enum[0];
|
59 | }
|
60 | }
|
61 |
|
62 |
|
63 | if (descriptor.numeric === true) {
|
64 | var _nextValidator = descriptor.validator;
|
65 | descriptor.type = [String, Number];
|
66 |
|
67 | descriptor.validator = function (value) {
|
68 | var infinite = descriptor.infinite,
|
69 | range = descriptor.range;
|
70 | return (infinite && (value === Infinity || value === -Infinity) || isNumeric(value)) && (Array.isArray(range) ? value >= range[0] && value <= range[1] : true) && (_nextValidator ? _nextValidator.apply(this, arguments) : true);
|
71 | };
|
72 | }
|
73 |
|
74 | var isModelProp = prop === model.prop;
|
75 | var event = isModelProp ? model.event : "update:" + prop;
|
76 | var shouldEmit = isModelProp || !!descriptor.sync;
|
77 | var shouldTransform = !!descriptor.transform;
|
78 | var shouldListen = descriptor.on && isFunction(descriptor.on.receive || descriptor.on.change);
|
79 | var shouldProcess = shouldEmit || shouldTransform;
|
80 | var onReceive = void 0;
|
81 | var onSend = void 0;
|
82 | var onChange = void 0;
|
83 | var on = descriptor.on;
|
84 |
|
85 | if ((shouldListen || shouldProcess) && isObject(on)) {
|
86 | if (isFunction(on.receive)) {
|
87 | onReceive = on.receive;
|
88 | }
|
89 |
|
90 | if (isFunction(on.send)) {
|
91 | onSend = on.send;
|
92 | }
|
93 |
|
94 | if (isFunction(on.change)) {
|
95 | onChange = on.change;
|
96 | }
|
97 | }
|
98 |
|
99 | if (shouldProcess) {
|
100 | var receiveTransform;
|
101 | var sendTransform;
|
102 | var transform = descriptor.transform;
|
103 |
|
104 | if (isFunction(transform)) {
|
105 | receiveTransform = transform;
|
106 | } else if (isObject(transform)) {
|
107 | if (isFunction(transform.receive)) {
|
108 | receiveTransform = transform.receive;
|
109 | }
|
110 |
|
111 | if (isFunction(transform.send)) {
|
112 | sendTransform = transform.send;
|
113 | }
|
114 | }
|
115 |
|
116 | var Prop = upperCaseFirst(prop);
|
117 | var localProp = "local" + Prop;
|
118 | var lastProp = "last" + Prop + "$$";
|
119 | var lastLocalProp = "lastLocal" + Prop + "$$";
|
120 | var sendProp = "send" + Prop;
|
121 | options.localDataKeys.push(localProp);
|
122 | options.watch[prop] = {
|
123 | immediate: true,
|
124 | handler: function handler(newValue, oldValue) {
|
125 | if (newValue === oldValue || newValue === this[lastLocalProp]) {
|
126 | this[lastProp] = newValue;
|
127 | return;
|
128 | }
|
129 |
|
130 | if (receiveTransform && newValue != null) {
|
131 | newValue = receiveTransform.call(this, newValue);
|
132 | if (newValue === oldValue || newValue === this[lastLocalProp]) return;
|
133 | }
|
134 |
|
135 | if (onReceive) {
|
136 | if (onReceive.call(this, newValue, oldValue) === false) {
|
137 | return;
|
138 | }
|
139 | }
|
140 |
|
141 | if (onChange) {
|
142 | if (onChange.call(this, newValue, oldValue) === false) {
|
143 | return;
|
144 | }
|
145 | }
|
146 |
|
147 | this[lastProp] = newValue;
|
148 | this[localProp] = newValue;
|
149 | }
|
150 | };
|
151 | options.watch[localProp] = {
|
152 | immediate: false,
|
153 | handler: function handler(newValue, oldValue) {
|
154 | if (newValue === oldValue || newValue === this[lastProp]) {
|
155 | this[lastLocalProp] = newValue;
|
156 | return;
|
157 | }
|
158 |
|
159 | if (sendTransform && newValue != null) {
|
160 | newValue = sendTransform.call(this, newValue);
|
161 | if (newValue === oldValue || newValue === this[lastProp]) return;
|
162 | }
|
163 |
|
164 | if (onSend) {
|
165 | if (onSend.call(this, newValue, oldValue) === false) {
|
166 | return;
|
167 | }
|
168 | }
|
169 |
|
170 | if (onChange) {
|
171 | if (onChange.call(this, newValue, oldValue) === false) {
|
172 | return;
|
173 | }
|
174 | }
|
175 |
|
176 | this[lastLocalProp] = newValue;
|
177 |
|
178 | if (shouldEmit) {
|
179 | this.$emit(event, newValue, oldValue);
|
180 | }
|
181 | }
|
182 | };
|
183 |
|
184 | if (shouldEmit) {
|
185 | options.methods[sendProp] = function (newValue) {
|
186 | this[localProp] = newValue;
|
187 | };
|
188 | }
|
189 | } else if (shouldListen) {
|
190 | options.watch[prop] = {
|
191 | immediate: true,
|
192 | handler: function handler(newValue, oldValue) {
|
193 | if (newValue === oldValue) return;
|
194 |
|
195 | if (onReceive) {
|
196 | onReceive.call(this, newValue, oldValue);
|
197 | }
|
198 |
|
199 | if (onChange) {
|
200 | onChange.call(this, newValue, oldValue);
|
201 | }
|
202 | }
|
203 | };
|
204 | }
|
205 | };
|
206 |
|
207 | for (var _i = 0; _i < _arr.length; _i++) {
|
208 | _loop();
|
209 | }
|
210 | },
|
211 | data: function data() {
|
212 | if (this.__MessengerData__) return;
|
213 | this.__MessengerData__ = true;
|
214 | return this.$options.localDataKeys.reduce(function (data, key) {
|
215 | data[key] = null;
|
216 | return data;
|
217 | }, {});
|
218 | }
|
219 | };
|
220 |
|
221 | module.exports = index;
|