1/* 2 * @file 3 * Integration with the colorbox library/module 4 */ 5 6(function ($) { 7 Drupal.ajax.prototype.commands.colorboxNodeReload = function (ajax, response) { 8 location.reload(); 9 }; 10 11 Drupal.ajax.prototype.commands.colorboxNodeRedirect = function (ajax, response) { 12 window.location.replace(response.data); 13 }; 14 15 Drupal.behaviors.colorboxNode = { 16 // Lets find our class name and change our URL to 17 // our defined menu path to open in a colorbox modal. 18 attach: function (context, settings) { 19 // Make sure colorbox exists. 20 if (!$.isFunction($.colorbox) || typeof settings.colorbox === 'undefined') { 21 return; 22 } 23 24 // Mobile detection extracted from the colorbox module. 25 // If the mobile setting is turned on, it will turn off the colorbox modal for mobile devices. 26 if (settings.colorbox.mobiledetect && window.matchMedia) { 27 // Disable Colorbox for small screens. 28 var mq = window.matchMedia("(max-device-width: " + settings.colorbox.mobiledevicewidth + ")"); 29 if (mq.matches) { 30 return; 31 } 32 } 33 34 $('.colorbox-node', context).once('init-colorbox-node-processed', function () { 35 $(this).colorboxNode({'launch': false}); 36 }); 37 38 // When using contextual links and clicking from within the colorbox 39 // we need to close down colorbox when opening the built in overlay. 40 $('ul.contextual-links a', context).once('colorboxNodeContextual').click(function () { 41 $.colorbox.close(); 42 }); 43 } 44 }; 45 46 $.fn.colorboxNodeLaunch = function (settings) { 47 var $this = $(this).clone(); 48 49 // Clear out the rel to prevent any confusion if not using the gallery class. 50 if(!$this.hasClass('colorbox-node-gallery')) { 51 $this.attr('rel', ''); 52 } 53 54 if (!hrefIsSafe(settings.href)) { 55 return; 56 } 57 // Lets extract our width and height giving priority to the data attributes. 58 var innerWidth = $this.data('inner-width'); 59 var innerHeight = $this.data('inner-height'); 60 if (typeof innerWidth != 'undefined' && typeof innerHeight != 'undefined') { 61 var params = $.urlDataParams(innerWidth, innerHeight); 62 } else { 63 var params = $.urlParams(settings.href); 64 } 65 66 // If we did not find a width or height, lets use the default. 67 if (params.innerHeight == undefined) { 68 params.innerHeight = settings.height; 69 } 70 if (params.innerWidth == undefined) { 71 params.innerWidth = settings.width; 72 } 73 74 params.html = '<div id="colorboxNodeLoading"></div>'; 75 params.onComplete = function () { 76 $this.colorboxNodeGroup(); 77 }; 78 params.open = true; 79 80 // Launch our colorbox with the provided settings 81 $this.colorbox($.extend({}, Drupal.settings.colorbox, params)); 82 }; 83 84 // Bind our colorbox node functionality to an anchor 85 $.fn.colorboxNode = function (options) { 86 var $this = this; 87 options = options || {}; 88 89 var settings = { 90 'launch': true, 91 'width': Drupal.settings.colorbox_node.width, 92 'height': Drupal.settings.colorbox_node.height 93 }; 94 95 $.extend(settings, options); 96 97 settings.href = $this.attr('data-href'); 98 if (typeof settings.href == 'undefined' || settings.href == false) { 99 settings.href = $this.attr('href'); 100 } 101 settings.href = Drupal.checkPlain(settings.href).replaceAll('&', '&'); 102 103 // Create an element so we can parse our a URL no matter if its internal or external. 104 var parse = document.createElement('a'); 105 parse.href = settings.href; 106 107 if(!settings.href) { 108 alert(Drupal.t('No url found on element')); 109 } 110 111 // Lets add our colorbox link after the base path if necessary. 112 var base_path = Drupal.settings.basePath; 113 var path_prefix = Drupal.settings.pathPrefix; 114 var pathname = parse.pathname; 115 116 // Lets check to see if the pathname has a forward slash. 117 // This problem happens in IE7/IE8 118 if (pathname.charAt(0) != '/') { 119 pathname = '/' + parse.pathname; 120 } 121 122 // If clean URL's are not turned on, lets check for that. 123 var cleanURLs = $.getParameterByName('q', settings.href); 124 if (base_path != '/') { 125 if (cleanURLs != '') { 126 settings.link = pathname.replace(base_path, base_path + parse.search.replace('?q=', '?q=/' + path_prefix + 'colorbox/')); 127 } else { 128 settings.link = pathname.replace(base_path, base_path + path_prefix + 'colorbox/') + parse.search; 129 } 130 } else { 131 if (cleanURLs != '') { 132 settings.link = base_path + parse.search.replace('?q=', '?q=/' + path_prefix + 'colorbox/'); 133 } else { 134 settings.link = base_path + path_prefix + 'colorbox' + pathname + parse.search; 135 } 136 } 137 138 // Bind Ajax behaviors to the element 139 var element_settings = {}; 140 element_settings.async = true; 141 142 // This removes any loading/progress bar on the clicked link 143 // and displays the colorbox loading screen instead. 144 element_settings.progress = { 'type': 'none' }; 145 // For anchor tags, these will go to the target of the anch
145or rather 146 // than the usual location. 147 if (settings.link) { 148 element_settings.url = settings.link; 149 element_settings.event = 'click'; 150 } 151 152 // Log our click handler to our ajax object 153 var base = Drupal.checkPlain($(this).attr('id')); 154 Drupal.ajax[base] = new Drupal.ajax(base, this, element_settings); 155 156 // Default to auto click for manual call to this function. 157 if (settings.launch) { 158 Drupal.ajax[base].eventResponse(this, 'click'); 159 $(this).colorboxNodeLaunch(settings); 160 } 161 else { 162 $(this).click(function () { 163 $(this).colorboxNodeLaunch(settings); 164 }); 165 } 166 }; 167 168 // Allow for grouping on links to showcase a gallery with left/right arrows. 169 // This function will find the next index of each link on the page by the rel 170 // and manually force a click on the link to call that AJAX and update the 171 // modal window. 172 $.fn.colorboxNodeGroup = function () { 173 // Lets do setup our gallery type of functions. 174 var $this = $(this); 175 var rel = Drupal.checkPlain($this.attr('rel')); 176 if (rel && $this.hasClass('colorbox-node-gallery')) { 177 if ($('a.colorbox-node-gallery[rel="' + rel + '"]:not(#colorbox a[rel="' + rel + '"])').length > 1) { 178 $related = $('a.colorbox-node-gallery[rel="' + rel + '"]:not(#colorbox a[rel="' + rel + '"])'); 179 180 // filter $related array by href, to have mutliple colorbox links to the same target 181 // appear as one item in the gallery only 182 var $related_unique = []; 183 $related.each(function () { 184 $.findHref($related_unique, this.href); 185 if (!$.findHref($related_unique, this.href).length) { 186 $related_unique.push(this); 187 } 188 }); 189 // we have to get the actual used element from the filtered list in order to get it's relative index 190 var current = $.findHref($related_unique, $this.get(0).href); 191 $related = $($related_unique); 192 var idx = $related.index($(current)); 193 var tot = $related.length; 194 195 // Show our gallery buttons 196 $('#cboxPrevious, #cboxNext').show(); 197 $.colorbox.next = function () { 198 index = get_index(1); 199 $related[index].click(); 200 }; 201 $.colorbox.prev = function () { 202 index = get_index(-1); 203 $related[index].click(); 204 }; 205 206 // Setup our current HTML 207 $('#cboxCurrent').html(Drupal.settings.colorbox.current.replace('{current}', idx + 1).replace('{total}', tot)).show(); 208 $('#cboxNext').html(Drupal.settings.colorbox.next).show(); 209 $('#cboxPrevious').html(Drupal.settings.colorbox.previous).show(); 210 211 var prefix = 'colorbox'; 212 // Remove Bindings and re-add 213 // @TODO: There must be a better way? If we don't remove it causes a memory to be exhausted. 214 $(document).unbind('keydown.' + prefix); 215 216 // Add Key Bindings 217 $(document).bind('keydown.' + prefix, function (e) { 218 var key = e.keyCode; 219 if ($related[1] && !e.altKey) { 220 if (key === 37) { 221 e.preventDefault(); 222 $.colorbox.prev(); 223 } else if (key === 39) { 224 e.preventDefault(); 225 $.colorbox.next(); 226 } 227 } 228 }); 229 } 230 231 function get_index(increment) { 232 var max = $related.length; 233 var newIndex = (idx + increment) % max; 234 return (newIndex < 0) ? max + newIndex : newIndex; 235 } 236 237 } 238 }; 239 240 // Find a colorbox link by href in an array 241 $.findHref = function (items, href) { 242 return $.grep(items, function (n, i) { 243 return n.href == href; 244 }); 245 }; 246 247 // Utility function to parse out our width/height from our url params
248 $.urlParams = function (url) { 249 var p = {}, 250 e, 251 a = /\+/g, // Regex for replacing addition symbol with a space 252 r = /([^&=]+)=?([^&]*)/g, 253 d = function (s) { 254 return decodeURIComponent(s.replace(a, ' ')); 255 }, 256 q = url.split('?'); 257 while (e = r.exec(q[1])) { 258 e[1] = d(e[1]); 259 e[2] = d(e[2]); 260 switch (e[2].toLowerCase()) { 261 case 'true': 262 case 'yes': 263 e[2] = true; 264 break; 265 266 case 'false': 267 case 'no': 268 e[2] = false; 269 break; 270 } 271 if (e[1] == 'width') { 272 e[1] = 'innerWidth'; 273 } 274 if (e[1] == 'height') { 275 e[1] = 'innerHeight'; 276 } 277 p[e[1]] = e[2]; 278 } 279 return p; 280 }; 281 282 // Utility function to return our data attributes for width/height 283 $.urlDataParams = function (innerWidth, innerHeight) { 284 return {'innerWidth':innerWidth,'innerHeight':innerHeight}; 285 }; 286 287 $.getParameterByName = function (name, href) { 288 name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]"); 289 var regexString = "[\\?&]" + name + "=([^&#]*)"; 290 var regex = new RegExp(regexString); 291 var found = regex.exec(href); 292 if (found == null) { 293 return ""; 294 } 295 else { 296 return decodeURIComponent(found[1].replace(/\+/g, " ")); 297 } 298 }; 299 300 /** 301 * Returns true if the passed-in href string is safe for colorbox_load. 302 * 303 * @param href 304 * The href string to be tested. 305 * 306 * @return 307 * Boolean true if the href is safe. 308 */ 309 function hrefIsSafe(href) { 310 var normalizedUrl = Drupal.absoluteUrl(href); 311 312 // Only local, non-file-system URLs are allowed. 313 if (!Drupal.urlIsLocal(normalizedUrl)) { 314 return false; 315 } 316 317 // Reject uploaded files from the public or private file system. 318 if (normalizedUrl.indexOf(Drupal.settings.colorbox.file_public_path) !== -1 || 319 normalizedUrl.match(/\/system\/files\//) || 320 normalizedUrl.match(/[?|&]q=system\/files\//)) { 321 return false; 322 } 323 324 // All checks passed. 325 return true; 326 } 327})(jQuery);
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.