1(function ($) { 2 3Drupal.behaviors.textarea = { 4 attach: function (context, settings) { 5 $('.form-textarea-wrapper.resizable', context).once('textarea', function () { 6 var staticOffset = null; 7 var textarea = $(this).addClass('resizable-textarea').find('textarea'); 8 var grippie = $('<div class="grippie"></div>').mousedown(startDrag); 9 10 grippie.insertAfter(textarea); 11 12 function startDrag(e) { 13 staticOffset = textarea.height() - e.pageY; 14 textarea.css('opacity', 0.25); 15 $(document).mousemove(performDrag).mouseup(endDrag); 16 return false; 17 } 18 19 function performDrag(e) { 20 textarea.height(Math.max(32, staticOffset + e.pageY) + 'px'); 21 return false; 22 } 23 24 function endDrag(e) { 25 $(document).unbind('mousemove', performDrag).unbind('mouseup', endDrag); 26 textarea.css('opacity', 1); 27 } 28 }); 29 } 30}; 31 32})(jQuery); 33; 34/** 35 * @file 36 * JavaScript behaviors for the front-end display of webforms. 37 */ 38 39(function ($) { 40 41Drupal.behaviors.webform = Drupal.behaviors.webform || {}; 42 43Drupal.behaviors.webform.attach = function (context) { 44 // Calendar datepicker behavior. 45 Drupal.webform.datepicker(context); 46}; 47 48Drupal.webform = Drupal.webform || {}; 49 50Drupal.webform.datepicker = function (context) { 51 $('div.webform-datepicker').each(function () { 52 var $webformDatepicker = $(this); 53 var $calendar = $webformDatepicker.find('input.webform-calendar'); 54 55 // Ensure the page we're on actually contains a datepicker. 56 if ($calendar.length == 0) { 57 return; 58 } 59 60 var startDate = $calendar[0].className.replace(/.*webform-calendar-start-(\d{4}-\d{2}-\d{2}).*/, '$1').split('-'); 61 var endDate = $calendar[0].className.replace(/.*webform-calendar-end-(\d{4}-\d{2}-\d{2}).*/, '$1').split('-'); 62 var firstDay = $calendar[0].className.replace(/.*webform-calendar-day-(\d).*/, '$1'); 63 // Convert date strings into actual Date objects. 64 startDate = new Date(startDate[0], startDate[1] - 1, startDate[2]); 65 endDate = new Date(endDate[0], endDate[1] - 1, endDate[2]); 66 67 // Ensure that start comes before end for datepicker. 68 if (startDate > endDate) { 69 var laterDate = startDate; 70 startDate = endDate; 71 endDate = laterDate; 72 } 73 74 var startYear = startDate.getFullYear(); 75 var endYear = endDate.getFullYear(); 76 77 // Set up the jQuery datepicker element. 78 $calendar.datepicker({ 79 dateFormat: 'yy-mm-dd', 80 yearRange: startYear + ':' + endYear, 81 firstDay: parseInt(firstDay), 82 minDate: startDate, 83 maxDate: endDate, 84 onSelect: function (dateText, inst) { 85 var date = dateText.split('-'); 86 $webformDatepicker.find('select.year, input.year').val(+date[0]).trigger('change'); 87 $webformDatepicker.find('select.month').val(+date[1]).trigger('change'); 88 $webformDatepicker.find('select.day').val(+date[2]).trigger('change'); 89 }, 90 beforeShow: function (input, inst) { 91 // Get the select list values. 92 var year = $webformDatepicker.find('select.year, input.year').val(); 93 var month = $webformDatepicker.find('select.month').val(); 94 var day = $webformDatepicker.find('select.day').val(); 95 96 // If empty, default to the current year/month/day in the popup. 97 var today = new Date(); 98 year = year ? year : today.getFullYear(); 99 month = month ? month : today.getMonth() + 1; 100 day = day ? day : today.getDate(); 101 102 // Make sure that the default year fits in the available options. 103 year = (year < startYear || year > endYear) ? startYear : year; 104 105 // jQuery UI Datepicker will read the input field and base its date off 106 // of that, even though in our case the input field is a button. 107 $(input).val(year + '-' + month + '-' + day); 108 } 109 }); 110 111 // Prevent the calendar button from submitting the form. 112 $calendar.click(function (event) { 113 $(this).focus(); 114 event.preventDefault(); 115 }); 116 }); 117} 118 119})(jQuery); 120; 121(function ($) { 122 123 // Need to keep this to check if there are extra parameters in the original URL. 124 var original = { 125 path: window.location.protocol + "//" + window.location.hostname + (window.location.port ? ':' + window.location.port: '') + window.location.pathname, 126 // @TODO integrate #1359798 without breaking history.js 127 query: window.location.search || '' 128 }; 129 130 /** 131 * Keep the original beforeSubmit method to use it later. 132 */ 133 var beforeSubmit = Drupal.ajax.prototype.beforeSubmit; 134 135 /** 136 * Keep the original beforeSerialize method to use it later. 137 */ 138 var beforeSerialize = Drupal.ajax.prototype.beforeSerialize; 139 140 Drupal.behaviors.viewsAjaxHistory = { 141 attach: function (context, settings) { 142 // Init the current page too, because the first loaded pager element do 143 // not have loadable history and will not work the back button. 144 var $body = $('body').once('views-ajax-history-first-page-load'); 145 if ($body.length) { 146 settings.viewsAjaxHistory.onloadPageItem = settings.viewsAjaxHistory.renderPageItem; 147 } 148 } 149 }; 150 151 /** 152 * Modification of Drupal.Views.parseQueryString() to allow extracting multivalues fields 153 * 154 * @param query 155 * String, either a full url or just the query string. 156 */ 157 var parseQueryString = function (query) { 158 var args = {}; 159 var pos = query.indexOf('?'); 160 if (pos != -1) { 161 query = query.substring(pos + 1); 162 } 163 var pairs = query.split('&'); 164 var pair, key, value; 165 for(var i in pairs) { 166 if (typeof(pairs[i]) == 'string') { 167 pair = pairs[i].split('='); 168 // Ignore the 'q' path argument, if present. 169 if (pair[0] != 'q' && pair[1]) { 170 key = decodeURIComponent(pair[0].replace(/\+/g, ' ')); 171 value = decodeURIComponent(pair[1].replace(/\+/g, ' ')); 172 // field name ends with [], it's multivalues 173 if (/\[\]$/.test(key)) { 174 if (!(key in args)) { 175 args[key] = [value]; 176 } 177 // don't duplicate values 178 else if (!$.inArray(value, args[key]) !== -1) { 179 args[key].push(value); 180 } 181 } 182 else { 183 args[key] = value; 184 } 185 } 186 } 187 } 188 return args; 189 }; 190 191 /** 192 * Strip views values and duplicates from URL 193 * 194 * @param url 195 * String with the full URL to clean up. 196 * @param viewArgs 197 * Object containing field values from views. 198 * 199 * @return url 200 * String URL with views values and reduced duplicates. 201 */ 202 var cleanURL = function (url, viewArgs) { 203 var args = parseQueryString(url); 204 var query = []; 205 206 // With clean urls off we need to add the 'q' parameter. 207 if (/\?/.test(Drupal.settings.views.ajax_path)) { 208 query.push('q=' + Drupal.Views.getPath(url)); 209 } 210 211 $.each(args, function (name, value) { 212 // use values from viewArgs if they exists 213 if (name in viewArgs) { 214 value = viewArgs[name]; 215 } 216 if ($.isArray(value)) { 217 $.merge(query, $.map(value, function (sub) { 218 return name + '=' + sub; 219 })); 220 } 221 else { 222 query.push(name + '=' + value); 223 } 224 }); 225 226 url = url.split('?'); 227 return url[0] + (query.length ? '?' + query.join('&') : ''); 228 }; 229 230 /** 231 * Unbind 'statechange' when adding a new state to avoid an infinite loop. 232 * 233 * We only use the 'statechange' event to trigger refresh on back of forward click. 234 * 235 * @param options 236 * Object containing the values from views' AJAX call. 237 * @param url 238 * String with the current URL to be cleaned up. 239 */ 240 var addState = function (options, url) { 241 // Store the actual view's dom id. 242 Drupal.settings.viewsAjaxHistory.lastViewDomID = options.data.view_dom_id; 243 $(window).unbind('statechange', loadView); 244 History.pushState(options, document.title, cleanURL(url, options.data)); 245 $(window).bind('statechange', loadView); 246 }; 247 248 /** 249 * Make an AJAX request to update the view when nagitating back and forth. 250 */ 251 var loadView = function () { 252 var state = History.getState(); 253 var options = state.data; 254 255 // This should be the first loaded page, so init the options object. 256 if (typeof options.data == 'undefined') { 257 var viewsAjaxSettingsKey = 'views_dom_id:' + Drupal.settings.viewsAjaxHistory.lastViewDomID; 258 if (Drupal.settings.views.ajaxViews.hasOwnProperty(viewsAjaxSettingsKey)) { 259 var viewsAjaxSettings = Drupal.settings.views.ajaxViews[viewsAjaxSettingsKey]; 260 viewsAjaxSettings.page = Drupal.settings.viewsAjaxHistory.onloadPageItem; 261 options = { 262 data: viewsAjaxSettings, 263 url: Drupal.settings.views.ajax_path 264 }; 265 } 266 } 267 268 // need a dummy element to trigger Drupal's AJAX call. 269 var $dummy = $('<div class="ajaxHistoryDummy"/>'); 270 // Drupal's AJAX options. 271 var settings = $.extend({ 272 submit: options.data, 273 setClick: true, 274 event: 'click', 275 selector: '.view-dom-id-' + options.data.view_dom_id, 276 progress: { type: 'throbber' } 277 }, options); 278 279 new Drupal.ajax(false, $dummy[0], settings);
280 // trigger ajax call 281 // @TODO check there is no leak, $dummy is never destroyed. 282 $dummy.trigger('click'); 283 }; 284 285 /** 286 * Override beforeSerialize to handle click on pager links 287 * 288 * @param $element 289 * jQuery DOM element 290 * @param options 291 */ 292 Drupal.ajax.prototype.beforeSerialize = function ($element, options) { 293 if (options.data.view_name) { 294 // If we're restoring a previous state the dummy element will have this class, 295 // and we don't need to go trough all this processing. 296 if ($($element).hasClass('ajaxHistoryDummy')) {return;} 297 298 options.url = Drupal.settings.views.ajax_path; 299 300 // Check we handle a click on a link, not a form submission. 301 if ($element.is('a')) { 302 addState(options, $element.attr('href')); 303 } 304 } 305 // Call the original Drupal method with the right context. 306 beforeSerialize.apply(this, arguments); 307 }; 308 309 /** 310 * Override beforeSubmit to handle exposed form submissions. 311 * 312 * @param form_values 313 * Object with all field values. 314 * @param element 315 * jQuery DOM form element. 316 * @param options 317 * Object containing AJAX options. 318 */ 319 Drupal.ajax.prototype.beforeSubmit = function (form_values, element, options) { 320 if (options.data.view_name) { 321 var url = original.path + (/\?/.test(original.path) ? '&' : '?') + element.formSerialize(); 322 323 // copy selected values in history state 324 $.each(form_values, function () { 325 // field name ending with [] is a multi value field 326 if (/\[\]$/.test(this.name)) { 327 if (!options.data[this.name]) { 328 options.data[this.name] = []; 329 } 330 options.data[this.name].push(this.value); 331 } 332 // regular field 333 else { 334 options.data[this.name] = this.value; 335 } 336 }); 337 338 addState(options, url); 339 } 340 341 for (var i = 0; i < arguments[0].length; i++) { 342 if (arguments[0][i].name == 'page') { 343 arguments[0][i].value = 0; 344 } 345 } 346 347 // Call the original Drupal method with the right context. 348 beforeSubmit.apply(this, arguments); 349 }; 350}(jQuery)); 351;
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.