Mercurial > hg > cmmr2012-drupal-site
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/misc/states.js Thu Jul 05 14:24:15 2018 +0000 @@ -0,0 +1,377 @@ +/** +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ + +(function ($, Drupal) { + var states = { + postponed: [] + }; + + Drupal.states = states; + + Drupal.behaviors.states = { + attach: function attach(context, settings) { + var $states = $(context).find('[data-drupal-states]'); + var il = $states.length; + + var _loop = function _loop(i) { + var config = JSON.parse($states[i].getAttribute('data-drupal-states')); + Object.keys(config || {}).forEach(function (state) { + new states.Dependent({ + element: $($states[i]), + state: states.State.sanitize(state), + constraints: config[state] + }); + }); + }; + + for (var i = 0; i < il; i++) { + _loop(i); + } + + while (states.postponed.length) { + states.postponed.shift()(); + } + } + }; + + states.Dependent = function (args) { + var _this = this; + + $.extend(this, { values: {}, oldValue: null }, args); + + this.dependees = this.getDependees(); + Object.keys(this.dependees || {}).forEach(function (selector) { + _this.initializeDependee(selector, _this.dependees[selector]); + }); + }; + + states.Dependent.comparisons = { + RegExp: function RegExp(reference, value) { + return reference.test(value); + }, + Function: function Function(reference, value) { + return reference(value); + }, + Number: function Number(reference, value) { + return typeof value === 'string' ? _compare2(reference.toString(), value) : _compare2(reference, value); + } + }; + + states.Dependent.prototype = { + initializeDependee: function initializeDependee(selector, dependeeStates) { + var state = void 0; + var self = this; + + function stateEventHandler(e) { + self.update(e.data.selector, e.data.state, e.value); + } + + this.values[selector] = {}; + + for (var i in dependeeStates) { + if (dependeeStates.hasOwnProperty(i)) { + state = dependeeStates[i]; + + if ($.inArray(state, dependeeStates) === -1) { + continue; + } + + state = states.State.sanitize(state); + + this.values[selector][state.name] = null; + + $(selector).on('state:' + state, { selector: selector, state: state }, stateEventHandler); + + new states.Trigger({ selector: selector, state: state }); + } + } + }, + compare: function compare(reference, selector, state) { + var value = this.values[selector][state.name]; + if (reference.constructor.name in states.Dependent.comparisons) { + return states.Dependent.comparisons[reference.constructor.name](reference, value); + } + + return _compare2(reference, value); + }, + update: function update(selector, state, value) { + if (value !== this.values[selector][state.name]) { + this.values[selector][state.name] = value; + this.reevaluate(); + } + }, + reevaluate: function reevaluate() { + var value = this.verifyConstraints(this.constraints); + + if (value !== this.oldValue) { + this.oldValue = value; + + value = invert(value, this.state.invert); + + this.element.trigger({ type: 'state:' + this.state, value: value, trigger: true }); + } + }, + verifyConstraints: function verifyConstraints(constraints, selector) { + var result = void 0; + if ($.isArray(constraints)) { + var hasXor = $.inArray('xor', constraints) === -1; + var len = constraints.length; + for (var i = 0; i < len; i++) { + if (constraints[i] !== 'xor') { + var constraint = this.checkConstraints(constraints[i], selector, i); + + if (constraint && (hasXor || result)) { + return hasXor; + } + result = result || constraint; + } + } + } else if ($.isPlainObject(constraints)) { + for (var n in constraints) { + if (constraints.hasOwnProperty(n)) { + result = ternary(result, this.checkConstraints(constraints[n], selector, n)); + + if (result === false) { + return false; + } + } + } + } + return result; + }, + checkConstraints: function checkConstraints(value, selector, state) { + if (typeof state !== 'string' || /[0-9]/.test(state[0])) { + state = null; + } else if (typeof selector === 'undefined') { + selector = state; + state = null; + } + + if (state !== null) { + state = states.State.sanitize(state); + return invert(this.compare(value, selector, state), state.invert); + } + + return this.verifyConstraints(value, selector); + }, + getDependees: function getDependees() { + var cache = {}; + + var _compare = this.compare; + this.compare = function (reference, selector, state) { + (cache[selector] || (cache[selector] = [])).push(state.name); + }; + + this.verifyConstraints(this.constraints); + + this.compare = _compare; + + return cache; + } + }; + + states.Trigger = function (args) { + $.extend(this, args); + + if (this.state in states.Trigger.states) { + this.element = $(this.selector); + + if (!this.element.data('trigger:' + this.state)) { + this.initialize(); + } + } + }; + + states.Trigger.prototype = { + initialize: function initialize() { + var _this2 = this; + + var trigger = states.Trigger.states[this.state]; + + if (typeof trigger === 'function') { + trigger.call(window, this.element); + } else { + Object.keys(trigger || {}).forEach(function (event) { + _this2.defaultTrigger(event, trigger[event]); + }); + } + + this.element.data('trigger:' + this.state, true); + }, + defaultTrigger: function defaultTrigger(event, valueFn) { + var oldValue = valueFn.call(this.element); + + this.element.on(event, $.proxy(function (e) { + var value = valueFn.call(this.element, e); + + if (oldValue !== value) { + this.element.trigger({ type: 'state:' + this.state, value: value, oldValue: oldValue }); + oldValue = value; + } + }, this)); + + states.postponed.push($.proxy(function () { + this.element.trigger({ type: 'state:' + this.state, value: oldValue, oldValue: null }); + }, this)); + } + }; + + states.Trigger.states = { + empty: { + keyup: function keyup() { + return this.val() === ''; + } + }, + + checked: { + change: function change() { + var checked = false; + this.each(function () { + checked = $(this).prop('checked'); + + return !checked; + }); + return checked; + } + }, + + value: { + keyup: function keyup() { + if (this.length > 1) { + return this.filter(':checked').val() || false; + } + return this.val(); + }, + change: function change() { + if (this.length > 1) { + return this.filter(':checked').val() || false; + } + return this.val(); + } + }, + + collapsed: { + collapsed: function collapsed(e) { + return typeof e !== 'undefined' && 'value' in e ? e.value : !this.is('[open]'); + } + } + }; + + states.State = function (state) { + this.pristine = state; + this.name = state; + + var process = true; + do { + while (this.name.charAt(0) === '!') { + this.name = this.name.substring(1); + this.invert = !this.invert; + } + + if (this.name in states.State.aliases) { + this.name = states.State.aliases[this.name]; + } else { + process = false; + } + } while (process); + }; + + states.State.sanitize = function (state) { + if (state instanceof states.State) { + return state; + } + + return new states.State(state); + }; + + states.State.aliases = { + enabled: '!disabled', + invisible: '!visible', + invalid: '!valid', + untouched: '!touched', + optional: '!required', + filled: '!empty', + unchecked: '!checked', + irrelevant: '!relevant', + expanded: '!collapsed', + open: '!collapsed', + closed: 'collapsed', + readwrite: '!readonly' + }; + + states.State.prototype = { + invert: false, + + toString: function toString() { + return this.name; + } + }; + + var $document = $(document); + $document.on('state:disabled', function (e) { + if (e.trigger) { + $(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); + } + }); + + $document.on('state:required', function (e) { + if (e.trigger) { + if (e.value) { + var label = 'label' + (e.target.id ? '[for=' + e.target.id + ']' : ''); + var $label = $(e.target).attr({ required: 'required', 'aria-required': 'aria-required' }).closest('.js-form-item, .js-form-wrapper').find(label); + + if (!$label.hasClass('js-form-required').length) { + $label.addClass('js-form-required form-required'); + } + } else { + $(e.target).removeAttr('required aria-required').closest('.js-form-item, .js-form-wrapper').find('label.js-form-required').removeClass('js-form-required form-required'); + } + } + }); + + $document.on('state:visible', function (e) { + if (e.trigger) { + $(e.target).closest('.js-form-item, .js-form-submit, .js-form-wrapper').toggle(e.value); + } + }); + + $document.on('state:checked', function (e) { + if (e.trigger) { + $(e.target).prop('checked', e.value); + } + }); + + $document.on('state:collapsed', function (e) { + if (e.trigger) { + if ($(e.target).is('[open]') === e.value) { + $(e.target).find('> summary').trigger('click'); + } + } + }); + + function ternary(a, b) { + if (typeof a === 'undefined') { + return b; + } else if (typeof b === 'undefined') { + return a; + } + + return a && b; + } + + function invert(a, invertState) { + return invertState && typeof a !== 'undefined' ? !a : a; + } + + function _compare2(a, b) { + if (a === b) { + return typeof a === 'undefined' ? a : true; + } + + return typeof a === 'undefined' || typeof b === 'undefined'; + } +})(jQuery, Drupal); \ No newline at end of file
