1(function ($, Drupal, drupalSettings) { 2 3 "use strict"; 4 5 Drupal.CohesionResponsiveBreakpoints = function (settings) { 6 7 this.constants = { 8 'desktop': 'desktop-first', 9 'mobile': 'mobile-first', 10 'widthType': { 11 'fluid': 'fluid', 12 'fixed': 'fixed' 13 }, 14 'mediaQuery': { 15 'all': 'all', 16 'max': 'max-width', 17 'min': 'min-width' 18 } 19 }; 20 21 // Custom responsive grid settings 22 this.settings = settings || drupalSettings.cohesion.responsive_grid_settings; 23 24 // Array of breakpoints in the correct order 25 this.breakpoints = []; 26 27 // Keyed list of listeners 28 this.listeners = {}; 29 30 /** 31 * Init when first loaded to do some setup 32 */ 33 this.init = function () { 34 35 this.sortBreakpoints(); 36 }; 37 38 /** 39 * Returns the current media query depending on the breakpoint "key" passed 40 * @param {string} breakpoint xs|ps|sm|md|lg|xl 41 */ 42 this.getBreakpointMediaQuery = function (breakpoint) { 43 44 if (this.getGridType() === this.constants.mobile) { 45 46 if (breakpoint === this.getFirstBreakpoint()) { 47 48 return this.constants.mediaQuery.all; 49 50 } else { 51 52 if (typeof this.getBreakpoints()[breakpoint] !== 'undefined') { 53 54 return '(min-width: ' + this.getBreakpointWidth(breakpoint) + 'px)'; 55 56 } else { 57 58 // Custom breakpoint 59 return '(min-width: ' + breakpoint + 'px)'; 60 } 61 } 62 } 63 64 if (this.getGridType() === this.constants.desktop) { 65 66 var breakpointIndex = this.getBreakpointIndex(breakpoint); 67 68 var minWidth = 0; 69 var breakpointMaxWidth = false; 70 71 if (breakpoint !== this.getLastBreakpoint()) { 72 minWidth = this.getBreakpointWidth(this.breakpoints[breakpointIndex].key); 73 } 74 75 if (breakpoint !== this.getFirstBreakpoint()) { 76 breakpointMaxWidth = this.getBreakpointWidth(this.breakpoints[breakpointIndex - 1].key) - 1; 77 } 78 79 var mediaQuery = '(min-width: ' + minWidth + 'px)'; 80 if (breakpointMaxWidth) { 81 mediaQuery = mediaQuery + ' and (max-width: ' + breakpointMaxWidth + 'px)'; 82 } 83 84 return mediaQuery; 85 } 86 }; 87 88 /** 89 * Returns the key for the first breakpoint (xs||ps) etc 90 * @returns {string} 91 */ 92 this.getFirstBreakpoint = function () { 93 return this.breakpoints[0].key; 94 }; 95 96 /** 97 * Returns the key for the last breakpoint (xs||ps) etc 98 * @returns {string} 99 */ 100 this.getLastBreakpoint = function () { 101 return this.breakpoints[this.breakpoints.length - 1].key; 102 }; 103 104 /** 105 * Get the current grid type mobile / desktop first 106 * @return {string} dekstop-fist || mobile-first 107 */ 108 this.getGridType = function () { 109 return this.settings.gridType; 110 }; 111 112 /** 113 * Simple helper function to determine if we are mobile first 114 * @returns {Boolean} 115 */ 116 this.isMobileFirst = function() { 117 return this.settings.gridType === this.constants.mobile; 118 }; 119 120 /** 121 * Simple helper function to determine if we are desktop first 122 * @returns {Boolean} 123 */ 124 this.isDesktopFirst = function() { 125 return this.settings.gridType === this.constants.desktop; 126 } 127 128 /** 129 * Gets the responsive width type - fluid || fixed 130 * @param {string} breakpoint xs|ps|sm|md|lg|xl 131 * @returns {string} fixed || fluid 132 */ 133 this.getBreakpointType = function (breakpoint) { 134 return this.settings.breakpoints[breakpoint].widthType; 135 }; 136 137 /** 138 * Returns the current breakpoint width depending on the breakpoint "key" passed 139 * @param {string} breakpoint xs|ps|sm|md|lg|xl 140 * @returns {int} breakpoint width 141 */ 142 this.getBreakpointWidth = function (breakpoint) { 143 return this.settings.breakpoints[breakpoint].width; 144 }; 145 146 /** 147 * Returns the min-width breakpoint 148 * @param {string} breakpoint xs|ps|sm|md|lg|xl 149 * @returns {int} 150 */
151 this.getBreakpointMediaWidth = function (breakpoint) { 152 153 if (this.getGridType() === this.constants.mobile) { 154 155 if (breakpoint === this.getFirstBreakpoint()) { 156 157 return 0; 158 159 } else { 160 161 if (typeof this.getBreakpoints()[breakpoint] !== 'undefined') { 162 163 return this.getBreakpointWidth(breakpoint); 164 165 } else { 166 167 // Custom breakpoint 168 return breakpoint; 169 } 170 } 171 } 172 173 if (this.getGridType() === this.constants.desktop) { 174 175 var breakpointIndex = this.getBreakpointIndex(breakpoint); 176 177 var minWidth = 0; 178 var breakpointMaxWidth = false; 179 180 if (typeof this.breakpoints[breakpointIndex - 1] !== 'undefined') { 181 minWidth = this.getBreakpointWidth(this.breakpoints[breakpointIndex].key); 182 } 183 184 if (breakpoint !== this.getFirstBreakpoint()) { 185 breakpointMaxWidth = this.getBreakpointWidth(this.breakpoints[breakpointIndex - 1].key) - 1; 186 } 187 188 var mediaQuery = '(min-width: ' + minWidth + 'px)'; 189 if (breakpointMaxWidth) { 190 mediaQuery = mediaQuery + ' and (max-width: ' + breakpointMaxWidth + 'px)'; 191 } 192 193 return breakpointMaxWidth; 194 } 195 196 }; 197 198 /** 199 * Returns the current breakpoint outerGutter depending on the breakpoint "key" passed 200 * @param {string} breakpoint xs|ps|sm|md|lg|xl 201 * @returns {int} outerGutter width 202 */ 203 this.getBreakpointOuterGutter = function (breakpoint) { 204 return this.settings.breakpoints[breakpoint].outerGutter; 205 }; 206 207 /** 208 * Returns the current breakpoint index depending on the breakpoint "key" passed 209 * @param {string} breakpoint xs|ps|sm|md|lg|xl 210 * @returns {int} position of the breakpoint 211 */ 212 this.getBreakpointIndex = function (breakpoint) { 213 for (var i = 0; i < this.breakpoints.length; i++) { 214 if (this.breakpoints[i].key === breakpoint) { 215 return i; 216 } 217 } 218 }; 219 220 /** 221 * Returns a list of the breakpoint settings 222 * @returns {object} 223 */ 224 this.getBreakpoints = function () { 225 return this.settings.breakpoints; 226 }; 227 228 /** 229 * Returns the settings for a specific breakpoint depending on the breakpoint "key" passed 230 * @param {string} breakpoint xs|ps|sm|md|lg|xl 231 */ 232 this.getBreakpointSettings = function (breakpoint) { 233 return this.settings.breakpoints[breakpoint]; 234 }; 235 236 /** 237 * Returns the settings for the current matched breakpoint 238 * @returns {object} 239 */ 240 this.getCurrentBreakpoint = function () { 241 242 var match = false; 243 244 for (var i = 0; i < this.breakpoints.length; i++) { 245 // Set the first item to match as this is the default 246 if (i === 0) { 247 match = this.breakpoints[i]; 248 } 249 250 // Check for matches 251 var m = window.matchMedia(this.getBreakpointMediaQuery(this.breakpoints[i].key)); 252 if (m.matches) { 253 match = this.breakpoints[i]; 254 } 255 } 256 return match; 257 }; 258 259 /** 260 * Patch to help out Safari understand where the object actually is 261 * @param {Object} - The returned `MediaQueryListEvent` from the `window` 262 * @returns {Object} - `MediaQueryListEvent` 263 */ 264 this.getMediaQueryListEventObject = function (mql) { 265 return typeof mql.target !== 'undefined' ? mql.target : mql; 266 }; 267 268 /** 269 * Shorthand method for this.getMediaQueryListEventObject() 270 * @param {Object} - The returned `MediaQueryListEvent` from the `window` 271 * @returns {Object} - `MediaQueryListEvent` 272 */ 273 this.getMql = function (mql) { 274 return this.getMediaQueryListEventObject(mql); 275 }; 276 277 /** 278 * @param {function} cb - the callback function to be executed at each breakpoint 279 * @returns {object} 280 */ 281 this.addListener = function (breakpoint, cb) { 282 283 }; 284 285 /** 286 * Run the callback with the correct settings 287 * @param {type} mql 288 * @param {type} key 289 * @param {type} callback 290 * @param {type} settings 291 * @returns {undefined} 292 */ 293 this.handleListener = function(mql, key, callback, callbackSettings) { 294 295 var _this = this; 296 297 if (!mql.matches && this.isDesktopFirst()) { 298 return; 299 } 300 301 // If there is no match in mobile first manually grab the current breakpoint settings as the user is most likely scaling down 302 if(!mql.matches && this.isMobileFirst()) { 303 key = _this.getCurrentBreakpoint().key; 304 mql = _this.listeners[key]; 305 } 306 307 mql = _this.getMql(mql); 308 309 mql.cohesion = { 310 'key': key, 311 'settings': callbackSettings 312 }; 313 314 return callback(mql); 315 }; 316 317 /** 318 * Binding of the native window.addListener 319 * @param {type} cb - the callback function to be executed at each breakpoint 320 * @returns {undefined} 321 */
322 this.addListeners = function (settings, callback) { 323 var _this = this; 324 var i, breakpointKey, mq, match; 325 326 for (i = 0; i < _this.breakpoints.length; i++) { 327 328 breakpointKey = _this.breakpoints[i].key; 329 mq = _this.getBreakpointMediaQuery(breakpointKey); 330 331 var listener; 332 listener = window.matchMedia(mq); 333 334 // Keep a record of the listeners 335 _this.listeners[breakpointKey] = listener; 336 337 listener.addListener(this.handleListener.bind(this, listener, breakpointKey, callback, settings)); 338 339 // Store a current match 340 if(listener.matches) { 341 match = listener; 342 match.key = breakpointKey; 343 } 344 } 345 346 // Run the callback for the first time 347 if(match) { 348 this.handleListener(match, match.key, callback, settings); 349 } 350 }; 351 352 /** 353 * Sorts the responsive breakpoints into the correct order 354 * @returns {array} 355 */ 356 this.sortBreakpoints = function () { 357 358 var _this = this; 359 360 var i = 0; 361 // Pass breakpoints into an array ready to be sorted 362 for (var k in _this.settings.breakpoints) { 363 if (_this.settings.breakpoints.hasOwnProperty(k)) { 364 _this.breakpoints.push(_this.settings.breakpoints[k]); 365 _this.breakpoints[i].key = k; 366 i++; 367 } 368 } 369 // Sort the array depending on mobile || desktop first 370 if (_this.getGridType() === _this.constants.mobile) { 371 372 _this.breakpoints.sort(function (a, b) { 373 return a.width - b.width; 374 }); 375 376 } else if (_this.getGridType() === _this.constants.desktop) { 377 378 _this.breakpoints.sort(function (a, b) { 379 return b.width - a.width; 380 }); 381 382 } else { 383 384 throw 'Mobile or Desktop first must be set in Website settings > Responsive grid settings'; 385 } 386 }; 387 388 // Init the 389 this.init(); 390 }; 391 392})(jQuery, Drupal, drupalSettings);
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.