Mercurial > hg > cmmr2012-drupal-site
comparison core/misc/states.js @ 0:c75dbcec494b
Initial commit from drush-created site
author | Chris Cannam |
---|---|
date | Thu, 05 Jul 2018 14:24:15 +0000 |
parents | |
children | a9cd425dd02b |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:c75dbcec494b |
---|---|
1 /** | |
2 * DO NOT EDIT THIS FILE. | |
3 * See the following change record for more information, | |
4 * https://www.drupal.org/node/2815083 | |
5 * @preserve | |
6 **/ | |
7 | |
8 (function ($, Drupal) { | |
9 var states = { | |
10 postponed: [] | |
11 }; | |
12 | |
13 Drupal.states = states; | |
14 | |
15 Drupal.behaviors.states = { | |
16 attach: function attach(context, settings) { | |
17 var $states = $(context).find('[data-drupal-states]'); | |
18 var il = $states.length; | |
19 | |
20 var _loop = function _loop(i) { | |
21 var config = JSON.parse($states[i].getAttribute('data-drupal-states')); | |
22 Object.keys(config || {}).forEach(function (state) { | |
23 new states.Dependent({ | |
24 element: $($states[i]), | |
25 state: states.State.sanitize(state), | |
26 constraints: config[state] | |
27 }); | |
28 }); | |
29 }; | |
30 | |
31 for (var i = 0; i < il; i++) { | |
32 _loop(i); | |
33 } | |
34 | |
35 while (states.postponed.length) { | |
36 states.postponed.shift()(); | |
37 } | |
38 } | |
39 }; | |
40 | |
41 states.Dependent = function (args) { | |
42 var _this = this; | |
43 | |
44 $.extend(this, { values: {}, oldValue: null }, args); | |
45 | |
46 this.dependees = this.getDependees(); | |
47 Object.keys(this.dependees || {}).forEach(function (selector) { | |
48 _this.initializeDependee(selector, _this.dependees[selector]); | |
49 }); | |
50 }; | |
51 | |
52 states.Dependent.comparisons = { | |
53 RegExp: function RegExp(reference, value) { | |
54 return reference.test(value); | |
55 }, | |
56 Function: function Function(reference, value) { | |
57 return reference(value); | |
58 }, | |
59 Number: function Number(reference, value) { | |
60 return typeof value === 'string' ? _compare2(reference.toString(), value) : _compare2(reference, value); | |
61 } | |
62 }; | |
63 | |
64 states.Dependent.prototype = { | |
65 initializeDependee: function initializeDependee(selector, dependeeStates) { | |
66 var state = void 0; | |
67 var self = this; | |
68 | |
69 function stateEventHandler(e) { | |
70 self.update(e.data.selector, e.data.state, e.value); | |
71 } | |
72 | |
73 this.values[selector] = {}; | |
74 | |
75 for (var i in dependeeStates) { | |
76 if (dependeeStates.hasOwnProperty(i)) { | |
77 state = dependeeStates[i]; | |
78 | |
79 if ($.inArray(state, dependeeStates) === -1) { | |
80 continue; | |
81 } | |
82 | |
83 state = states.State.sanitize(state); | |
84 | |
85 this.values[selector][state.name] = null; | |
86 | |
87 $(selector).on('state:' + state, { selector: selector, state: state }, stateEventHandler); | |
88 | |
89 new states.Trigger({ selector: selector, state: state }); | |
90 } | |
91 } | |
92 }, | |
93 compare: function compare(reference, selector, state) { | |
94 var value = this.values[selector][state.name]; | |
95 if (reference.constructor.name in states.Dependent.comparisons) { | |
96 return states.Dependent.comparisons[reference.constructor.name](reference, value); | |
97 } | |
98 | |
99 return _compare2(reference, value); | |
100 }, | |
101 update: function update(selector, state, value) { | |
102 if (value !== this.values[selector][state.name]) { | |
103 this.values[selector][state.name] = value; | |
104 this.reevaluate(); | |
105 } | |
106 }, | |
107 reevaluate: function reevaluate() { | |
108 var value = this.verifyConstraints(this.constraints); | |
109 | |
110 if (value !== this.oldValue) { | |
111 this.oldValue = value; | |
112 | |
113 value = invert(value, this.state.invert); | |
114 | |
115 this.element.trigger({ type: 'state:' + this.state, value: value, trigger: true }); | |
116 } | |
117 }, | |
118 verifyConstraints: function verifyConstraints(constraints, selector) { | |
119 var result = void 0; | |
120 if ($.isArray(constraints)) { | |
121 var hasXor = $.inArray('xor', constraints) === -1; | |
122 var len = constraints.length; | |
123 for (var i = 0; i < len; i++) { | |
124 if (constraints[i] !== 'xor') { | |
125 var constraint = this.checkConstraints(constraints[i], selector, i); | |
126 | |
127 if (constraint && (hasXor || result)) { | |
128 return hasXor; | |
129 } | |
130 result = result || constraint; | |
131 } | |
132 } | |
133 } else if ($.isPlainObject(constraints)) { | |
134 for (var n in constraints) { | |
135 if (constraints.hasOwnProperty(n)) { | |
136 result = ternary(result, this.checkConstraints(constraints[n], selector, n)); | |
137 | |
138 if (result === false) { | |
139 return false; | |
140 } | |
141 } | |
142 } | |
143 } | |
144 return result; | |
145 }, | |
146 checkConstraints: function checkConstraints(value, selector, state) { | |
147 if (typeof state !== 'string' || /[0-9]/.test(state[0])) { | |
148 state = null; | |
149 } else if (typeof selector === 'undefined') { | |
150 selector = state; | |
151 state = null; | |
152 } | |
153 | |
154 if (state !== null) { | |
155 state = states.State.sanitize(state); | |
156 return invert(this.compare(value, selector, state), state.invert); | |
157 } | |
158 | |
159 return this.verifyConstraints(value, selector); | |
160 }, | |
161 getDependees: function getDependees() { | |
162 var cache = {}; | |
163 | |
164 var _compare = this.compare; | |
165 this.compare = function (reference, selector, state) { | |
166 (cache[selector] || (cache[selector] = [])).push(state.name); | |
167 }; | |
168 | |
169 this.verifyConstraints(this.constraints); | |
170 | |
171 this.compare = _compare; | |
172 | |
173 return cache; | |
174 } | |
175 }; | |
176 | |
177 states.Trigger = function (args) { | |
178 $.extend(this, args); | |
179 | |
180 if (this.state in states.Trigger.states) { | |
181 this.element = $(this.selector); | |
182 | |
183 if (!this.element.data('trigger:' + this.state)) { | |
184 this.initialize(); | |
185 } | |
186 } | |
187 }; | |
188 | |
189 states.Trigger.prototype = { | |
190 initialize: function initialize() { | |
191 var _this2 = this; | |
192 | |
193 var trigger = states.Trigger.states[this.state]; | |
194 | |
195 if (typeof trigger === 'function') { | |
196 trigger.call(window, this.element); | |
197 } else { | |
198 Object.keys(trigger || {}).forEach(function (event) { | |
199 _this2.defaultTrigger(event, trigger[event]); | |
200 }); | |
201 } | |
202 | |
203 this.element.data('trigger:' + this.state, true); | |
204 }, | |
205 defaultTrigger: function defaultTrigger(event, valueFn) { | |
206 var oldValue = valueFn.call(this.element); | |
207 | |
208 this.element.on(event, $.proxy(function (e) { | |
209 var value = valueFn.call(this.element, e); | |
210 | |
211 if (oldValue !== value) { | |
212 this.element.trigger({ type: 'state:' + this.state, value: value, oldValue: oldValue }); | |
213 oldValue = value; | |
214 } | |
215 }, this)); | |
216 | |
217 states.postponed.push($.proxy(function () { | |
218 this.element.trigger({ type: 'state:' + this.state, value: oldValue, oldValue: null }); | |
219 }, this)); | |
220 } | |
221 }; | |
222 | |
223 states.Trigger.states = { | |
224 empty: { | |
225 keyup: function keyup() { | |
226 return this.val() === ''; | |
227 } | |
228 }, | |
229 | |
230 checked: { | |
231 change: function change() { | |
232 var checked = false; | |
233 this.each(function () { | |
234 checked = $(this).prop('checked'); | |
235 | |
236 return !checked; | |
237 }); | |
238 return checked; | |
239 } | |
240 }, | |
241 | |
242 value: { | |
243 keyup: function keyup() { | |
244 if (this.length > 1) { | |
245 return this.filter(':checked').val() || false; | |
246 } | |
247 return this.val(); | |
248 }, | |
249 change: function change() { | |
250 if (this.length > 1) { | |
251 return this.filter(':checked').val() || false; | |
252 } | |
253 return this.val(); | |
254 } | |
255 }, | |
256 | |
257 collapsed: { | |
258 collapsed: function collapsed(e) { | |
259 return typeof e !== 'undefined' && 'value' in e ? e.value : !this.is('[open]'); | |
260 } | |
261 } | |
262 }; | |
263 | |
264 states.State = function (state) { | |
265 this.pristine = state; | |
266 this.name = state; | |
267 | |
268 var process = true; | |
269 do { | |
270 while (this.name.charAt(0) === '!') { | |
271 this.name = this.name.substring(1); | |
272 this.invert = !this.invert; | |
273 } | |
274 | |
275 if (this.name in states.State.aliases) { | |
276 this.name = states.State.aliases[this.name]; | |
277 } else { | |
278 process = false; | |
279 } | |
280 } while (process); | |
281 }; | |
282 | |
283 states.State.sanitize = function (state) { | |
284 if (state instanceof states.State) { | |
285 return state; | |
286 } | |
287 | |
288 return new states.State(state); | |
289 }; | |
290 | |
291 states.State.aliases = { | |
292 enabled: '!disabled', | |
293 invisible: '!visible', | |
294 invalid: '!valid', | |
295 untouched: '!touched', | |
296 optional: '!required', | |
297 filled: '!empty', | |
298 unchecked: '!checked', | |
299 irrelevant: '!relevant', | |
300 expanded: '!collapsed', | |
301 open: '!collapsed', | |
302 closed: 'collapsed', | |
303 readwrite: '!readonly' | |
304 }; | |
305 | |
306 states.State.prototype = { | |
307 invert: false, | |
308 | |
309 toString: function toString() { | |
310 return this.name; | |
311 } | |
312 }; | |
313 | |
314 var $document = $(document); | |
315 $document.on('state:disabled', function (e) { | |
316 if (e.trigger) { | |
317 $(e.target).prop('disabled', e.value).closest('.js-form-item, .js-form-submit, .js-form-wrapper').toggleClass('form-disabled', e.value).find('select, input, textarea').prop('disabled', e.value); | |
318 } | |
319 }); | |
320 | |
321 $document.on('state:required', function (e) { | |
322 if (e.trigger) { | |
323 if (e.value) { | |
324 var label = 'label' + (e.target.id ? '[for=' + e.target.id + ']' : ''); | |
325 var $label = $(e.target).attr({ required: 'required', 'aria-required': 'aria-required' }).closest('.js-form-item, .js-form-wrapper').find(label); | |
326 | |
327 if (!$label.hasClass('js-form-required').length) { | |
328 $label.addClass('js-form-required form-required'); | |
329 } | |
330 } else { | |
331 $(e.target).removeAttr('required aria-required').closest('.js-form-item, .js-form-wrapper').find('label.js-form-required').removeClass('js-form-required form-required'); | |
332 } | |
333 } | |
334 }); | |
335 | |
336 $document.on('state:visible', function (e) { | |
337 if (e.trigger) { | |
338 $(e.target).closest('.js-form-item, .js-form-submit, .js-form-wrapper').toggle(e.value); | |
339 } | |
340 }); | |
341 | |
342 $document.on('state:checked', function (e) { | |
343 if (e.trigger) { | |
344 $(e.target).prop('checked', e.value); | |
345 } | |
346 }); | |
347 | |
348 $document.on('state:collapsed', function (e) { | |
349 if (e.trigger) { | |
350 if ($(e.target).is('[open]') === e.value) { | |
351 $(e.target).find('> summary').trigger('click'); | |
352 } | |
353 } | |
354 }); | |
355 | |
356 function ternary(a, b) { | |
357 if (typeof a === 'undefined') { | |
358 return b; | |
359 } else if (typeof b === 'undefined') { | |
360 return a; | |
361 } | |
362 | |
363 return a && b; | |
364 } | |
365 | |
366 function invert(a, invertState) { | |
367 return invertState && typeof a !== 'undefined' ? !a : a; | |
368 } | |
369 | |
370 function _compare2(a, b) { | |
371 if (a === b) { | |
372 return typeof a === 'undefined' ? a : true; | |
373 } | |
374 | |
375 return typeof a === 'undefined' || typeof b === 'undefined'; | |
376 } | |
377 })(jQuery, Drupal); |