1(function ($, Drupal) { 2 3 'use strict'; 4 5 // Create the defaults once 6 var cmm = new Drupal.CohesionResponsiveBreakpoints(); 7 8 var pluginName = 'cohesionContainerMatchHeights'; 9 10 var defaults = { 11 current: false, 12 excludeElements: ['column'], 13 expressionPrefixes: ['>', '> .coh-column'], 14 loadersPrefix: '.coh-row > .coh-row-inner', 15 elements : { 16 'none': { 17 'parent': 'none', 18 'child': false 19 }, 20 'h1': { 21 'parent': 'h1', 22 'child': false 23 }, 24 'h2': { 25 'parent': 'h2', 26 'child': false 27 }, 28 'h3': { 29 'parent': 'h3', 30 'child': false 31 }, 32 'h4': { 33 'parent': 'h4', 34 'child': false 35 }, 36 'h5': { 37 'parent': 'h5', 38 'child': false 39 }, 40 'h6': { 41 'parent': 'h6', 42 'child': false 43 }, 44 'p': { 45 'parent': 'p', 46 'child': false 47 }, 48 'list-container': { 49 'parent': '.coh-list-container', 50 'child': false 51 }, 52 'container': { 53 'parent': '.coh-container', 54 'child': false 55 }, 56 'wysiwyg': { 57 'parent': '.coh-wysiwyg', 58 'child': false 59 }, 60 'hyperlink': { 61 'parent': 'a', 62 'child': false 63 }, 64 'blockquote': { 65 'parent': 'blockquote', 66 'child': false 67 }, 68 'slide': { 69 'parent': '.slick-list > .slick-track > .coh-slider-item', 70 'child': false 71 }, 72 'iframe': { 73 'parent': '.coh-iframe', 74 'child': false 75 }, 76 'youtube-video-background': { 77 'parent': '.coh-youtube-video-background', 78 'child': false 79 } 80 }, 81 loaders: [ 82 '.coh-row > .coh-row-inner frame', 83 '.coh-row > .coh-row-inner iframe', 84 '.coh-row > .coh-row-inner img', 85 '.coh-row > .coh-row-inner input[type="image"]', 86 '.coh-row > .coh-row-inner link', 87 '.coh-row > .coh-row-inner script', 88 '.coh-row > .coh-row-inner style' 89 ] 90 }; 91 92 // The actual plugin constructor 93 function ccmh(element, options) { 94 95 this.element = element; 96 this.$element = $(element); 97 98 this.options = $.extend({}, defaults, options); 99 this._defaults = defaults; 100 101 this._name = pluginName; 102 this._current = false; 103 104 this.init(); 105 } 106 107 ccmh.prototype.init = function () { 108 // Place initialization logic here 109 // Already have access to the DOM element and the options via the instance, 110 // e.g., this.element and this.options 111 112 var _self = this; 113 var key = ''; 114 var previous = { 115 target: 'none' 116 }; 117 118 var settings = {}; 119 settings._self = _self; 120 settings.breakpoints = {}; 121 122 for (var i = 0; i < cmm.breakpoints.length; i++) { 123 124 key = cmm.breakpoints[i].key; 125 126 settings.breakpoints[key] = previous; 127 128 if (typeof _self.options.targets[key] !== 'undefined') { 129 130 settings.breakpoints[key] = _self.options.targets[key]; 131 132 previous = _self.options.targets[key]; 133 134 } else { 135 136 if (typeof cmm.breakpoints[i - 1] !== 'undefined' && typeof previous !== false) { 137 138 settings.breakpoints[key] = previous; 139 140 _self.options.targets[key] = {}; 141 _self.options.targets[key] = previous; 142 } 143 } 144 } 145 146 // Bind the listeners 147 cmm.addListeners(settings, _self.setMatchHeightsCallback); 148 149 // Once the ajax has finished loading AND anything else that could effect the layout (onload) 150 $(_self.options.context).ajaxComplete(function (event, xhr, settings) { 151 152 $.fn.matchHeight._update(); 153 154 $(_self.options.loaders.toString(), _self.options.context).on('load', function () { 155 if ($(this).length) { 156 $.fn.matchHeight._update(); 157 } 158 }); 159 }); 160 }; 161 162 /** 163 * Grabs the HTML Element / Class from our mapper otherwise turns the value into a class 164 * @param {String} elementKey - the key of `this.settings.elements` 165 * @returns CSS selector from the mapper || generates a custom class 166 */ 167 ccmh.prototype.getElement = function (elementKey) { 168 var element; 169 170 // If the value exists in 'elements' then use this otherwise hopefully this is a CSS class
171 if (this.options.elements.hasOwnProperty(elementKey)) { 172 element = this.options.elements[elementKey]; 173 } else { 174 element = elementKey.match(/^[.]/) ? elementKey : '.' + elementKey; 175 } 176 177 return element; 178 }; 179 180 /** 181 * Generates the jQuery selector 182 * @param {String} element - the key of `this.settings.elements` 183 * @param {Int} targetLevel (optional) 184 * @returns jQuery selector 185 */ 186 ccmh.prototype.getElementExpression = function (element, targetLevel) { 187 188 var expression = [], 189 prefixes = [''], 190 el = this.getElement(element), 191 elementIsClass = typeof el === 'string', 192 depth = typeof targetLevel !== 'undefined' ? targetLevel : false; 193 194 if(this.options.excludeElements.indexOf(element) < 0) { 195 prefixes = this.options.expressionPrefixes; 196 } 197 198 for (var i = 0; i < prefixes.length; i++) { 199 200 if(!elementIsClass) { 201 // Append the parent element 202 // If element, the element should be an immediately inside 203 expression[i] = prefixes[i] + ' > ' + el.parent; 204 } else { 205 // Append the parent element 206 207 // If Custom class then drill down to the class to any level 208 expression[i] = prefixes[i] + ' ' + el; 209 } 210 211 // Append the :nth-of-type 212 if(depth !== false) { 213 expression[i] = expression[i] + ':nth-of-type(' + depth + ')'; 214 } 215 216 // Append any children 217 if(!elementIsClass && el.child) { 218 expression[i] = expression[i] + ' > ' + el.child; 219 } 220 } 221 return expression.join(', '); 222 }; 223 224 /** 225 * Initialises match heights 226 * @param {Object} settings - object of the breakpoints 227 * @returns {jQuery obj} - match heights jQuery object 228 */ 229 ccmh.prototype.setMatchHeights = function (settings) { 230 231 var _self = this; 232 233 var target = settings.cohesion.settings.breakpoints[settings.cohesion.key]; 234 235 // If the breakpoint is false do not set anything - just let it inherit or do its thing 236 if(typeof target === 'undefined' || target === false) { 237 return; 238 } 239 240 var el = _self.getElement(target.target); 241 242 _self.destroyMatchHeights(); 243 244 if (el !== 'none') { 245 246 var expression = _self.getElementExpression(target.target, target.targetLevel); 247 248 // Save the current matches so we can destroy it later 249 _self._current = $(expression, _self.$element); 250 251 return _self._current.matchHeight({ 252 byRow: false 253 }); 254 } 255 }; 256 257 /** 258 * Wrapper for when the callback is returned so we can apply the correct scope 259 * @param {type} settings 260 * @returns {undefined} 261 */ 262 ccmh.prototype.setMatchHeightsCallback = function(settings) { 263 264 var _self = settings.cohesion.settings._self || this; 265 266 return _self.setMatchHeights(settings); 267 }; 268 269 /** 270 * Destroys match heights for the current instance 271 * @returns {unresolved} 272 */ 273 ccmh.prototype.destroyMatchHeights = function () { 274 return $(this._current).matchHeight({ 275 remove: true 276 }); 277 }; 278 279 280 // A really lightweight plugin wrapper around the constructor, 281 // preventing against multiple instantiations 282 $.fn[pluginName] = function (options) { 283 return this.each(function () { 284 if (!$.data(this, 'plugin_' + pluginName)) { 285 $.data(this, 'plugin_' + pluginName, new ccmh(this, options)); 286 } 287 }); 288 }; 289 290})(jQuery, Drupal);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.