1Drupal.locale = { 'pluralFormula': function ($n) { return Number(($n!=1)); }, 'strings': {"":{"An AJAX HTTP error occurred.":"\u0412\u044a\u0437\u043d\u0438\u043a\u043d\u0430 AJAX HTTP \u0433\u0440\u0435\u0448\u043a\u0430","HTTP Result Code: !status":"\u041f\u043e\u043b\u0443\u0447\u0435\u043d \u0435 HTTP \u043a\u043e\u0434 :!status","An AJAX HTTP request terminated abnormally.":"HTTP \u0437\u0430\u044f\u0432\u043a\u0430\u0442\u0430 \u043d\u0430 AJAX \u043d\u0435 \u0437\u0430\u0432\u044a\u0440\u0448\u0438 \u043d\u043e\u0440\u043c\u0430\u043b\u043d\u043e","Debugging information follows.":"\u0421\u043b\u0435\u0434\u0432\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0437\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430","Path: !uri":"\u041f\u044a\u0442: !uri","StatusText: !statusText":"\u0421\u0442\u0430\u0442\u0443\u0441 \u0442\u0435\u043a\u0441\u0442: !statusText","ResponseText: !responseText":"ResponseText: !responseText","ReadyState: !readyState":"ReadyState: !readyState","Next":"\u041a\u0430\u0447\u0438","Status":"\u0421\u0442\u0430\u0442\u0443\u0441","Cancel":"\u041e\u0442\u043c\u0435\u043d\u0438","Disabled":"\u0414\u0435\u0430\u043a\u0442\u0438\u0432\u0438\u0440\u0430\u043d","Enabled":"\u0410\u043a\u0442\u0438\u0432\u0438\u0440\u0430\u043d","Edit":"\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0430\u0439","Date":"\u0414\u0430\u0442\u0430","Size":"\u0420\u0430\u0437\u043c\u0435\u0440","Search":"\u0422\u044a\u0440\u0441\u0438","none":"\u043d\u0435","Sunday":"\u043d\u0435\u0434\u0435\u043b\u044f","Monday":"\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u043d\u0438\u043a","Tuesday":"\u0432\u0442\u043e\u0440\u043d\u0438\u043a","Wednesday":"\u0441\u0440\u044f\u0434\u0430","Thursday":"\u0447\u0435\u0442\u0432\u044a\u0440\u0442\u044a\u043a","Friday":"\u043f\u0435\u0442\u044a\u043a","Saturday":"\u0441\u044a\u0431\u043e\u0442\u0430","Add":"\u0414\u043e\u0431\u0430\u0432\u0438","Filename":"\u0418\u043c\u0435 \u043d\u0430 \u0444\u0430\u0439\u043b\u0430","Menu":"\u041c\u0435\u043d\u044e","Configure":"\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u0430\u0439","All":"\u0412\u0441\u0438\u0447\u043a\u0438","Done":"\u0413\u043e\u0442\u043e\u0432\u043e","N\/A":"N\/A","OK":"OK","This field is required.":"\u0417\u0430\u0434\u044a\u043b\u0436\u0438\u0442\u0435\u043b\u043d\u043e \u043f\u043e\u043b\u0435.","Mon":"\u041f\u043e\u043d.","Tue":"\u0412\u0442.","Wed":"\u0421\u0440.","Thu":"\u0412\u0442.","Fri":"\u041f\u0435\u0442.","Sat":"\u0421\u044a\u0431.","Sun":"\u041d\u0435\u0434.","January":"\u042f\u043d\u0443\u0430\u0440\u0438","February":"\u0424\u0435\u0432\u0440\u0443\u0430\u0440\u0438","March":"\u041c\u0430\u0440\u0442","April":"\u0410\u043f\u0440\u0438\u043b","May":"\u041c\u0430\u0439","June":"\u042e\u043d\u0438","July":"\u042e\u043b\u0438","August":"\u0410\u0432\u0433\u0443\u0441\u0442","September":"\u0421\u0435\u043f\u0442\u0435\u043c\u0432\u0440\u0438","October":"\u041e\u043a\u0442\u043e\u043c\u0432\u0440\u0438","November":"\u041d\u043e\u0435\u043c\u0432\u0440\u0438","December":"\u0414\u0435\u043a\u0435\u043c\u0432\u0440\u0438","Show":"\u041f\u043e\u043a\u0430\u0436\u0438","Select all rows in this table":"\u0418\u0437\u0431\u0435\u0440\u0435\u0442\u0435 \u0432\u0441\u0438\u0447\u043a\u0438 \u0440\u0435\u0434\u043e\u0432\u0435 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0430\u0442\u0430","Deselect all rows in this table":"\u041e\u0442\u043a\u0430\u0436\u0438 \u0432\u0441\u0438\u0447\u043a\u0438 \u0440\u0435\u0434\u043e\u0432\u0435 \u043e\u0442 \u0442\u0430\u0431\u043b\u0438\u0446\u0430\u0442\u0430","Jan":"\u042f\u043d.","Feb":"\u0424\u0435\u0432\u0440.","Mar":"\u041c\u0430\u0440\u0442","Apr":"\u0410\u043f\u0440.","Jun":"\u042e\u043d\u0438","Jul":"\u042e\u043b\u0438","Aug":"\u0410\u0432\u0433.","Sep":"\u0421\u0435\u043f\u0442.","Oct":"\u041e\u043a\u0442.","Nov":"\u041d\u043e\u0435\u043c.","Dec":"\u0414\u0435\u043a.","Not published":"\u041d\u0435\u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0432\u0430\u043d\u043e","Shortcuts":"\u041f\u0440\u0435\u043a\u0438 \u043f\u044a\u0442\u0438\u0449\u0430","Please wait...":"\u041c\u043e\u043b\u044f \u0438\u0437\u0447\u0430\u043a\u0430\u0439\u0442\u0435...","Hide":"\u0421\u043a\u0440\u0438\u0439","Loading":"\u0417\u0430\u0440\u0435\u0436\u0434\u0430\u043d\u0435","By @name on @date":"\u
1041e\u0442 @name \u043d\u0430 @date","By @name":"\u041e\u0442 @name","Not in menu":"\u041d\u0435 \u0435 \u0432\u043a\u043b\u044e\u0447\u0435\u043d \u0432 \u043c\u0435\u043d\u044e\u0442\u043e","Alias: @alias":"\u0421\u0438\u043d\u043e\u043d\u0438\u043c: @alias","No alias":"\u041b\u0438\u043f\u0441\u0432\u0430 \u0441\u0438\u043d\u043e\u043d\u0438\u043c","New revision":"\u041d\u043e\u0432\u0430 \u0432\u0435\u0440\u0441\u0438\u044f","Drag to re-order":"\u0412\u043b\u0430\u0447\u0438 \u0437\u0430 \u043f\u0440\u043e\u043c\u044f\u043d\u0430 \u043d\u0430 \u043f\u043e\u0434\u0440\u0435\u0434\u0431\u0430\u0442\u0430","Changes made in this table will not be saved until the form is submitted.":"\u041f\u0440\u043e\u043c\u0435\u043d\u0438\u0442\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u0435\u043d\u0438 \u0432 \u0442\u0430\u0437\u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u0430, \u043d\u044f\u043c\u0430 \u0434\u0430 \u0441\u0435 \u0437\u0430\u043f\u0438\u0448\u0430\u0442 \u043f\u0440\u0435\u0434\u0438 \u0444\u043e\u0440\u043c\u0430\u0442\u0430 \u0434\u0430 \u0435 \u0438\u0437\u043f\u0440\u0430\u0442\u0435\u043d\u0430.","The changes to these blocks will not be saved until the \u003Cem\u003ESave blocks\u003C\/em\u003E button is clicked.":"\u041f\u0440\u043e\u043c\u0435\u043d\u0438\u0442\u0435 \u0432 \u0442\u0435\u0437\u0438 \u0431\u043b\u043e\u043a\u043e\u0432\u0435 \u043d\u044f\u043c\u0430 \u0434\u0430 \u0431\u044a\u0434\u0430\u0442 \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u0438, \u0434\u043e\u043a\u0430\u0442\u043e \u043d\u0435 \u0431\u044a\u0434\u0435 \u043d\u0430\u0442\u0438\u0441\u043d\u0430\u0442 \u0431\u0443\u0442\u043e\u043d\u0430 \u003Cem\u003E\u0417\u0430\u043f\u0438\u0448\u0438 \u0431\u043b\u043e\u043a\u043e\u0432\u0435\u003C\/em\u003E.","Show shortcuts":"\u041f\u043e\u043a\u0430\u0436\u0438 \u043f\u0440\u0435\u043a\u0438\u0442\u0435 \u043f\u044a\u0442\u0438\u0449\u0430","No revision":"\u041d\u044f\u043c\u0430 \u0432\u0435\u0440\u0441\u0438\u044f","@number comments per page":"@number \u043a\u043e\u043c\u0435\u043d\u0442\u0430\u0440\u0438 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430","(active tab)":"(\u0430\u043a\u0442\u0438\u0432\u0435\u043d \u0440\u0430\u0437\u0434\u0435\u043b)","Customize dashboard":"\u041e\u0444\u043e\u0440\u043c\u0438 \u0442\u0430\u0431\u043b\u043e\u0442\u043e","Hide summary":"\u0421\u043a\u0440\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 \u0440\u0435\u0437\u044e\u043c\u0435","Edit summary":"\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0440\u0435\u0437\u044e\u043c\u0435","@title dialog":"@title \u0434\u0438\u0430\u043b\u043e\u0433","The selected file %filename cannot be uploaded. Only files with the following extensions are allowed: %extensions.":"\u0418\u0437\u0431\u0440\u0430\u043d\u0438\u044f\u0442 \u0444\u0430\u0439\u043b %filename \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0431\u044a\u0434\u0435 \u043a\u0430\u0447\u0435\u043d. \u0421\u0430\u043c\u043e \u0444\u0430\u0439\u043b\u043e\u0432\u0435 \u0441\u044a\u0441\u0441\u043b\u0435\u0434\u043d\u0438\u0442\u0435 \u0440\u0430\u0437\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u0441\u0430 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438: %extensions.","Re-order rows by numerical weight instead of dragging.":"\u041f\u0440\u0435\u043d\u0430\u0440\u0435\u0434\u0438 \u0440\u0435\u0434\u043e\u0432\u0435\u0442\u0435 \u043f\u043e \u0442\u0435\u0433\u043b\u043e, \u0432\u043c\u0435\u0441\u0442\u043e \u0441 \u0432\u043b\u0430\u0447\u0435\u043d\u0435","Show row weights":"\u041f\u043e\u043a\u0430\u0436\u0438 \u0442\u0435\u0433\u043b\u043e\u0442\u043e \u043d\u0430 \u0440\u0435\u0434\u043e\u0432\u0435\u0442\u0435","Hide row weights":"\u0421\u043a\u0440\u0438\u0439 \u0440\u0435\u0434\u043e\u0432\u0435\u0442\u0435 \u0441 \u0442\u0435\u0433\u043b\u043e","Autocomplete popup":"\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u0437\u0430\u043f\u044a\u043b\u0432\u0430\u043d\u0435 \u043d\u0430 \u0438\u0437\u0441\u043a\u0430\u0447\u0430\u0449\u0438 \u043f\u0440\u043e\u0437\u043e\u0440\u0446\u0438","Searching for matches...":"\u0422\u044a\u0440\u0441\u0435\u043d\u0435 \u043d\u0430 \u0441\u044a\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u044f...","Hide shortcuts":"\u0421\u043a\u0440\u0438\u0439 \u043f\u0440\u0435\u043a\u0438\u0442\u0435 \u043f\u044a\u0442\u0438\u0449\u0430","Submit":"\u0418\u0437\u043f\u0440\u0430\u0442\u0438","Apply (all displays)":"\u0418\u0437\u043f\u0440\u0430\u0442\u0438","Apply (this display)":"\u0418\u0437\u043f\u0440\u0430\u0442\u0438","Select":"\u0418\u0437\u0431\u0435\u0440\u0435\u0442\u0435"}} };; 2function getParameterByName(name, url) { 3 if (!url) url = window.location.href; 4 name = name.replace(/[\[\]]/g, '\\$&'); 5 var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'), 6 results = regex.exec(url); 7 if (!results) return null; 8 if (!results[2]) return ''; 9 return decodeURIComponent(results[2].replace(/\+/g, ' ')); 10} 11function urlencode(text) { 12 return encodeURIComponent(text).replace(/!/g, '%21') 13 .replace(/'/g, '%27') 14 .replace(/\(/g, '%28') 15 .replace(/\)/g, '%29') 16 .replace(/\*/g, '%2A') 17 .replace(/%20/g, '+'); 18} 19jQuery(document).ready(function () { 20 console.log('encode url 2.0'); 21 22 var destination = getParameterByName('destination'); 23 var sid = getParameterByName('sid') 24 if(!destination) { 25 return; 26 } 27 jQuery('.tabs a').each(function () { 28 console.log(jQuery(this).attr('href')); 29 jQuery(this).attr('href', jQuery(this).attr('href') + '?sid=' + sid + '&destination=' + urlencode(destination)) 30 }) 31}); 32(function ($) { 33 34 Drupal.behaviors.captcha = { 35 attach: function (context) { 36 37 // Turn off autocompletion for the CAPTCHA response field. 38 // We do it here with JavaScript (instead of directly in the markup) 39 // because this autocomplete attribute is not standard and 40 // it would break (X)HTML compliance. 41 $("#edit-captcha-response").attr("autocomplete", "off"); 42 43 } 44 }; 45 46 Drupal.behaviors.captchaAdmin = { 47 attach: function (context) {
48 // Add onclick handler to checkbox for adding a CAPTCHA description 49 // so that the textfields for the CAPTCHA description are hidden 50 // when no description should be added. 51 // @todo: div.form-item-captcha-description depends on theming, maybe 52 // it's better to add our own wrapper with id (instead of a class). 53 $("#edit-captcha-add-captcha-description").click(function() { 54 if ($("#edit-captcha-add-captcha-description").is(":checked")) { 55 // Show the CAPTCHA description textfield(s). 56 $("div.form-item-captcha-description").show('slow'); 57 } 58 else { 59 // Hide the CAPTCHA description textfield(s). 60 $("div.form-item-captcha-description").hide('slow'); 61 } 62 }); 63 // Hide the CAPTCHA description textfields if option is disabled on page load. 64 if (!$("#edit-captcha-add-captcha-description").is(":checked")) { 65 $("div.form-item-captcha-description").hide(); 66 } 67 } 68 69 }; 70 71})(jQuery); 72; 73(function ($) { 74 75Drupal.behaviors.textarea = { 76 attach: function (context, settings) { 77 $('.form-textarea-wrapper.resizable', context).once('textarea', function () { 78 var staticOffset = null; 79 var textarea = $(this).addClass('resizable-textarea').find('textarea'); 80 var grippie = $('<div class="grippie"></div>').mousedown(startDrag); 81 82 grippie.insertAfter(textarea); 83 84 function startDrag(e) { 85 staticOffset = textarea.height() - e.pageY; 86 textarea.css('opacity', 0.25); 87 $(document).mousemove(performDrag).mouseup(endDrag); 88 return false; 89 } 90 91 function performDrag(e) { 92 textarea.height(Math.max(32, staticOffset + e.pageY) + 'px'); 93 return false; 94 } 95 96 function endDrag(e) { 97 $(document).unbind('mousemove', performDrag).unbind('mouseup', endDrag); 98 textarea.css('opacity', 1); 99 } 100 }); 101 } 102}; 103 104})(jQuery); 105; 106(function ($) { 107 108/** 109 * Attach handlers to evaluate the strength of any password fields and to check 110 * that its confirmation is correct. 111 */ 112Drupal.behaviors.password = { 113 attach: function (context, settings) { 114 var translate = settings.password; 115 $('input.password-field', context).once('password', function () { 116 var passwordInput = $(this); 117 var innerWrapper = $(this).parent(); 118 var outerWrapper = $(this).parent().parent(); 119 120 // Add identifying class to password element parent. 121 innerWrapper.addClass('password-parent'); 122 123 // Add the password confirmation layer. 124 $('input.password-confirm', outerWrapper).parent().prepend('<div class="password-confirm">' + translate['confirmTitle'] + ' <span></span></div>').addClass('confirm-parent'); 125 var confirmInput = $('input.password-confirm', outerWrapper); 126 var confirmResult = $('div.password-confirm', outerWrapper); 127 var confirmChild = $('span', confirmResult); 128 129 // Add the description box. 130 var passwordMeter = '<div class="password-strength"><div class="password-strength-text" aria-live="assertive"></div><div class="password-strength-title">' + translate['strengthTitle'] + '</div><div class="password-indicator"><div class="indicator"></div></div></div>'; 131 $(confirmInput).parent().after('<div class="password-suggestions description"></div>'); 132 $(innerWrapper).prepend(passwordMeter); 133 var passwordDescription = $('div.password-suggestions', outerWrapper).hide(); 134 135 // Check the password strength. 136 var passwordCheck = function () { 137 138 // Evaluate the password strength. 139 var result = Drupal.evaluatePasswordStrength(passwordInput.val(), settings.password); 140 141 // Update the suggestions for how to improve the password. 142 if (passwordDescription.html() != result.message) { 143 passwordDescription.html(result.message); 144 } 145 146 // Only show the description box if there is a weakness in the password. 147 if (result.strength == 100) { 148 passwordDescription.hide(); 149 } 150 else { 151 passwordDescription.show(); 152 } 153 154 // Adjust the length of the strength indicator. 155 $(innerWrapper).find('.indicator').css('width', result.strength + '%'); 156 157 // Update the strength indication text. 158 $(innerWrapper).find('.password-strength-text').html(result.indicatorText); 159 160 passwordCheckMatch(); 161 }; 162 163 // Check that password and confirmation inputs match. 164 var passwordCheckMatch = function () { 165 166 if (confirmInput.val()) { 167 var success = passwordInput.val() === confirmInput.val(); 168 169 // Show the confirm result. 170 confirmResult.css({ visibility: 'visible' }); 171 172 // Remove the previous styling if any exists. 173 if (this.confirmClass) { 174 confirmChild.removeClass(this.confirmClass); 175 } 176 177 // Fill in the success message and set the class accordingly. 178 var confirmClass = success ? 'ok' : 'error'; 179 confirmChild.html(translate['confirm' + (success ? 'Success' : 'Failure')]).addClass(confirmClass); 180 this.confirmClass = confirmClass; 181 } 182 else { 183 confirmResult.css({ visibility: 'hidden' }); 184 } 185 }; 186 187 // Monitor keyup and blur events. 188 // Blur must be used because a mouse paste does not trigger keyup.
189 passwordInput.keyup(passwordCheck).focus(passwordCheck).blur(passwordCheck); 190 confirmInput.keyup(passwordCheckMatch).blur(passwordCheckMatch); 191 }); 192 } 193}; 194 195/** 196 * Evaluate the strength of a user's password. 197 * 198 * Returns the estimated strength and the relevant output message. 199 */ 200Drupal.evaluatePasswordStrength = function (password, translate) { 201 password = $.trim(password); 202 203 var weaknesses = 0, strength = 100, msg = []; 204 205 var hasLowercase = /[a-z]+/.test(password); 206 var hasUppercase = /[A-Z]+/.test(password); 207 var hasNumbers = /[0-9]+/.test(password); 208 var hasPunctuation = /[^a-zA-Z0-9]+/.test(password); 209 210 // If there is a username edit box on the page, compare password to that, otherwise 211 // use value from the database. 212 var usernameBox = $('input.username'); 213 var username = (usernameBox.length > 0) ? usernameBox.val() : translate.username; 214 215 // Lose 5 points for every character less than 6, plus a 30 point penalty. 216 if (password.length < 6) { 217 msg.push(translate.tooShort); 218 strength -= ((6 - password.length) * 5) + 30; 219 } 220 221 // Count weaknesses. 222 if (!hasLowercase) { 223 msg.push(translate.addLowerCase); 224 weaknesses++; 225 } 226 if (!hasUppercase) { 227 msg.push(translate.addUpperCase); 228 weaknesses++; 229 } 230 if (!hasNumbers) { 231 msg.push(translate.addNumbers); 232 weaknesses++; 233 } 234 if (!hasPunctuation) { 235 msg.push(translate.addPunctuation); 236 weaknesses++; 237 } 238 239 // Apply penalty for each weakness (balanced against length penalty). 240 switch (weaknesses) { 241 case 1: 242 strength -= 12.5; 243 break; 244 245 case 2: 246 strength -= 25; 247 break; 248 249 case 3: 250 strength -= 40; 251 break; 252 253 case 4: 254 strength -= 40; 255 break; 256 } 257 258 // Check if password is the same as the username. 259 if (password !== '' && password.toLowerCase() === username.toLowerCase()) { 260 msg.push(translate.sameAsUsername); 261 // Passwords the same as username are always very weak. 262 strength = 5; 263 } 264 265 // Based on the strength, work out what text should be shown by the password strength meter. 266 if (strength < 60) { 267 indicatorText = translate.weak; 268 } else if (strength < 70) { 269 indicatorText = translate.fair; 270 } else if (strength < 80) { 271 indicatorText = translate.good; 272 } else if (strength <= 100) { 273 indicatorText = translate.strong; 274 } 275 276 // Assemble the final message. 277 msg = translate.hasWeaknesses + '<ul><li>' + msg.join('</li><li>') + '</li></ul>'; 278 return { strength: strength, message: msg, indicatorText: indicatorText }; 279 280}; 281 282/** 283 * Field instance settings screen: force the 'Display on registration form' 284 * checkbox checked whenever 'Required' is checked. 285 */ 286Drupal.behaviors.fieldUserRegistration = { 287 attach: function (context, settings) { 288 var $checkbox = $('form#field-ui-field-edit-form input#edit-instance-settings-user-register-form'); 289 290 if ($checkbox.length) { 291 $('input#edit-instance-required', context).once('user-register-form-checkbox', function () { 292 $(this).bind('change', function (e) { 293 if ($(this).attr('checked')) { 294 $checkbox.attr('checked', true); 295 } 296 }); 297 }); 298 299 } 300 } 301}; 302 303})(jQuery); 304; 305(function ($) { 306 307/** 308 * A progressbar object. Initialized with the given id. Must be inserted into 309 * the DOM afterwards through progressBar.element. 310 * 311 * method is the function which will perform the HTTP request to get the 312 * progress bar state. Either "GET" or "POST". 313 * 314 * e.g. pb = new progressBar('myProgressBar'); 315 * some_element.appendChild(pb.element); 316 */ 317Drupal.progressBar = function (id, updateCallback, method, errorCallback) { 318 var pb = this; 319 this.id = id; 320 this.method = method || 'GET'; 321 this.updateCallback = updateCallback; 322 this.errorCallback = errorCallback; 323 324 // The WAI-ARIA setting aria-live="polite" will announce changes after users 325 // have completed their current activity and not interrupt the screen reader. 326 this.element = $('<div class="progress" aria-live="polite"></div>').attr('id', id); 327 this.element.html('<div class="bar"><div class="filled"></div></div>' + 328 '<div class="percentage"></div>' + 329 '<div class="message"> </div>'); 330}; 331 332/** 333 * Set the percentage and status message for the progressbar. 334 */ 335Drupal.progressBar.prototype.setProgress = function (percentage, message) { 336 if (percentage >= 0 && percentage <= 100) { 337 $('div.filled', this.element).css('width', percentage + '%'); 338 $('div.percentage', this.element).html(percentage + '%'); 339 } 340 $('div.message', this.element).html(message); 341 if (this.updateCallback) { 342 this.updateCallback(percentage, message, this); 343 } 344}; 345 346/** 347 * Start monitoring progress via Ajax. 348 */ 349Drupal.progressBar.prototype.startMonitoring = function (uri, delay) { 350 this.delay = delay; 351 this.uri = uri; 352 this.sendPing(); 353}; 354 355/** 356 * Stop monitoring progress via Ajax. 357 */ 358Drupal.progressBar.prototype.stopMonitoring = function () { 359 clearTimeout(this.timer); 360 // This allows monitoring to be stopped from within the callback. 361 this.uri = null; 362}; 363 364/** 365 * Request progress data from server. 366 */ 367Drupal.progressBar.prototype.sendPing = function () { 368 if (this.timer) { 369 clearTimeout(this.timer); 370 } 371 if (this.uri) { 372 var pb = this; 373 // When doing a post request, you need non-null data. Otherwise a 374 // HTTP 411 or HTTP 406 (with Apache mod_security) error may result. 375 $.ajax({ 376 type: this.method, 377 url: this.uri, 378 data: '', 379 dataType: 'json', 380 success: function (progress) { 381 // Display errors. 382 if (progress.status == 0) { 383 pb.displayError(progress.data); 384 return; 385 } 386 // Update display. 387 pb.setProgress(progress.percentage, progress.message); 388 // Schedule next timer.
389 pb.timer = setTimeout(function () { pb.sendPing(); }, pb.delay); 390 }, 391 error: function (xmlhttp) { 392 pb.displayError(Drupal.ajaxError(xmlhttp, pb.uri)); 393 } 394 }); 395 } 396}; 397 398/** 399 * Display errors on the page. 400 */ 401Drupal.progressBar.prototype.displayError = function (string) { 402 var error = $('<div class="messages error"></div>').html(string); 403 $(this.element).before(error).hide(); 404 405 if (this.errorCallback) { 406 this.errorCallback(this); 407 } 408}; 409 410})(jQuery); 411; 412/** 413 * @file 414 * JavaScript behaviors for the front-end display of webforms. 415 */ 416 417(function ($) { 418 419 "use strict"; 420 421 Drupal.behaviors.webform = Drupal.behaviors.webform || {}; 422 423 Drupal.behaviors.webform.attach = function (context) { 424 // Calendar datepicker behavior. 425 Drupal.webform.datepicker(context); 426 427 // Conditional logic. 428 if (Drupal.settings.webform && Drupal.settings.webform.conditionals) { 429 Drupal.webform.conditional(context); 430 } 431 }; 432 433 Drupal.webform = Drupal.webform || {}; 434 435 Drupal.webform.datepicker = function (context) { 436 $('div.webform-datepicker').each(function () { 437 var $webformDatepicker = $(this); 438 var $calendar = $webformDatepicker.find('input.webform-calendar'); 439 440 // Ensure the page we're on actually contains a datepicker. 441 if ($calendar.length == 0) { 442 return; 443 } 444 445 var startDate = $calendar[0].className.replace(/.*webform-calendar-start-(\d{4}-\d{2}-\d{2}).*/, '$1').split('-'); 446 var endDate = $calendar[0].className.replace(/.*webform-calendar-end-(\d{4}-\d{2}-\d{2}).*/, '$1').split('-'); 447 var firstDay = $calendar[0].className.replace(/.*webform-calendar-day-(\d).*/, '$1'); 448 // Convert date strings into actual Date objects. 449 startDate = new Date(startDate[0], startDate[1] - 1, startDate[2]); 450 endDate = new Date(endDate[0], endDate[1] - 1, endDate[2]); 451 452 // Ensure that start comes before end for datepicker. 453 if (startDate > endDate) { 454 var laterDate = startDate; 455 startDate = endDate; 456 endDate = laterDate; 457 } 458 459 var startYear = startDate.getFullYear(); 460 var endYear = endDate.getFullYear(); 461 462 // Set up the jQuery datepicker element. 463 $calendar.datepicker({ 464 dateFormat: 'yy-mm-dd', 465 yearRange: startYear + ':' + endYear, 466 firstDay: parseInt(firstDay), 467 minDate: startDate, 468 maxDate: endDate, 469 onSelect: function (dateText, inst) { 470 var date = dateText.split('-'); 471 $webformDatepicker.find('select.year, input.year').val(+date[0]).trigger('change'); 472 $webformDatepicker.find('select.month').val(+date[1]).trigger('change'); 473 $webformDatepicker.find('select.day').val(+date[2]).trigger('change'); 474 }, 475 beforeShow: function (input, inst) { 476 // Get the select list values. 477 var year = $webformDatepicker.find('select.year, input.year').val(); 478 var month = $webformDatepicker.find('select.month').val(); 479 var day = $webformDatepicker.find('select.day').val(); 480 481 // If empty, default to the current year/month/day in the popup. 482 var today = new Date(); 483 year = year ? year : today.getFullYear(); 484 month = month ? month : today.getMonth() + 1; 485 day = day ? day : today.getDate(); 486 487 // Make sure that the default year fits in the available options. 488 year = (year < startYear || year > endYear) ? startYear : year; 489 490 // jQuery UI Datepicker will read the input field and base its date 491 // off of that, even though in our case the input field is a button. 492 $(input).val(year + '-' + month + '-' + day); 493 } 494 }); 495 496 // Prevent the calendar button from submitting the form. 497 $calendar.click(function (event) { 498 // This event is triggered also when pressing enter when the focus is on 499 // previous webform components, but we only want to do something when 500 // we are on the calendar component. By checking the event client x/y 501 // position we known if it was the user clicking. For keyboard navigators 502 // simply the focus handles the date picker so we don't have to do 503 // anything special for them. 504 if (event.clientX !== 0 && event.clientY !== 0) { 505 // Focus is only necessary for Safari. But it has no impact on other 506 // browsers. 507 $(this).focus(); 508 event.preventDefault(); 509 } 510 }); 511 512 // Clear date on backspace or delete. 513 $calendar.keyup(function (e) { 514 if (e.keyCode == 8 || e.keyCode == 46) { 515 $.datepicker._clearDate(this); 516 } 517 }); 518 }); 519 }; 520 521 Drupal.webform.conditional = function (context) { 522 // Add the bindings to each webform on the page. 523 $.each(Drupal.settings.webform.conditionals, function (formKey, settings) { 524 var $form = $('.' + formKey + ':not(.webform-conditional-processed)'); 525 $form.each(function (index, currentForm) { 526 var $currentForm = $(currentForm); 527 $currentForm.addClass('webform-conditional-processed'); 528 $currentForm.bind('change', {'settings': settings}, Drupal.webform.conditionalCheck); 529 530 // Trigger all the elements that cause conditionals on this form. 531 Drupal.webform.doConditions($currentForm, settings); 532 }); 533 }); 534 }; 535 536 /** 537 * Event handler to respond to field changes in a form. 538 * 539 * This event is bound to the entire form, not individual fields. 540 */ 541 Drupal.webform.conditionalCheck = function (e) { 542 var $triggerElement = $(e.target).closest('.webform-component'); 543 if (!$triggerElement.length) { 544 return; 545 } 546 var $form = $triggerElement.closest('form'); 547 var triggerElementKey = $triggerElement.attr('class').match(/webform-component--[^ ]+/)[0]; 548 var settings = e.data.settings; 549 if (settings.sourceMap[triggerElementKey]) { 550 Drupal.webform.doConditions($form, settings); 551 } 552 }; 553 554 /** 555 * Processes all conditional. 556 */ 557 Drupal.webform.doConditions = function ($form, settings) { 558 559 var stackPointer; 560 var resultStack; 561 562 /** 563 * Initializes an execution stack for a conditional group's rules. 564 * 565 * Also initializes sub-conditional rules. 566 */ 567 function executionStackInitialize(andor) { 568 stackPointer = -1; 569 resultStack = []; 570 executionStackPush(andor); 571 } 572 573 /** 574 * Starts a new subconditional for the given and/or operator. 575 */ 576 function executionStackPush(andor) { 577 resultStack[++stackPointer] = { 578 results: [], 579 andor: andor, 580 }; 581 } 582 583 /** 584 * Adds a rule's result to the current sub-conditional. 585 */ 586 function executionStackAccumulate(result) { 587 resultStack[stackPointer]['results'].push(result); 588 } 589 590 /** 591 * Finishes a sub-conditional and adds the result to the parent stack frame. 592 */ 593 function executionStackPop() { 594 // Calculate the and/or result. 595 var stackFrame = resultStack[stackPointer]; 596 // Pop stack and protect against stack underflow. 597 stackPointer = Math.max(0, stackPointer - 1); 598 var $conditionalResults = stackFrame['results']; 599 var filteredResults = $.map($conditionalResults, function (val) { 600 return val ? val : null; 601 }); 602 return stackFrame['andor'] === 'or' 603 ? filteredResults.length > 0 604 : filteredResults.length === $conditionalResults.length; 605 } 606 607 // Track what has been set/hidden for each target component's elements. 608 // Hidden elements must be disabled because if they are required and don't 609 // have a value, they will prevent submission due to html5 validation. 610 // Each execution of the conditionals adds a temporary class 611 // webform-disabled-flag so that elements hidden or set can be disabled and 612 // also be prevented from being re-enabled by another conditional (such as a 613 // parent fieldset). After processing conditionals, this temporary class 614 // must be removed in preparation for the next execution of the 615 // conditionals. 616 $.each(settings.ruleGroups, function (rgid_key, rule_group) { 617 var ruleGroup = settings.ruleGroups[rgid_key]; 618 619 // Perform the comparison callback and build the results for this group. 620 executionStackInitialize(ruleGroup['andor']); 621 $.each(ruleGroup['rules'], function (m, rule) { 622 switch (rule['source_type']) { 623 case 'component':
624 var elementKey = rule['source']; 625 var element = $form.find('.' + elementKey)[0]; 626 var existingValue = settings.values[elementKey] ? settings.values[elementKey] : null; 627 executionStackAccumulate(window['Drupal']['webform'][rule.callback](element, existingValue, rule['value'])); 628 break; 629 630 case 'conditional_start': 631 executionStackPush(rule['andor']); 632 break; 633 634 case 'conditional_end': 635 executionStackAccumulate(executionStackPop()); 636 break; 637 } 638 }); 639 var conditionalResult = executionStackPop(); 640 641 $.each(ruleGroup['actions'], function (aid, action) { 642 var $target = $form.find('.' + action['target']); 643 var actionResult = action['invert'] ? !conditionalResult : conditionalResult; 644 switch (action['action']) { 645 case 'show': 646 var changed = actionResult != Drupal.webform.isVisible($target); 647 if (actionResult) { 648 $target.find('.webform-conditional-disabled:not(.webform-disabled-flag)') 649 .removeClass('webform-conditional-disabled') 650 .webformProp('disabled', false); 651 $target 652 .removeClass('webform-conditional-hidden') 653 .show(); 654 $form.find('.chosen-disabled').prev().trigger('chosen:updated.chosen'); 655 } 656 else { 657 $target 658 .hide() 659 .addClass('webform-conditional-hidden') 660 .find(':input') 661 .addClass('webform-conditional-disabled webform-disabled-flag') 662 .webformProp('disabled', true); 663 } 664 if (changed && $target.is('tr')) { 665 Drupal.webform.restripeTable($target.closest('table').first()); 666 } 667 break; 668 669 case 'require': 670 var $requiredSpan = $target.find('.form-required, .form-optional').first(); 671 if (actionResult != $requiredSpan.hasClass('form-required')) { 672 var $targetInputElements = $target.find("input:text,textarea,input[type='email'],select,input:radio,input:checkbox,input:file"); 673 // Rather than hide the required tag, remove it so that other 674 // jQuery can respond via Drupal behaviors. 675 Drupal.detachBehaviors($requiredSpan); 676 $targetInputElements 677 .webformProp('required', actionResult) 678 .toggleClass('required', actionResult); 679 if (actionResult) { 680 $requiredSpan.replaceWith('<span class="form-required" title="' + Drupal.t('This field is required.') + '">*</span>'); 681 } 682 else { 683 $requiredSpan.replaceWith('<span class="form-optional"></span>'); 684 } 685 Drupal.attachBehaviors($requiredSpan); 686 } 687 break; 688 689 case 'set': 690 var $texts = $target.find("input:text,textarea,input[type='email']"); 691 var $selects = $target.find('select,select option,input:radio,input:checkbox'); 692 var $markups = $target.filter('.webform-component-markup'); 693 if (actionResult) { 694 var multiple = $.map(action['argument'].split(','), $.trim); 695 $selects 696 .webformVal(multiple) 697 .webformProp('disabled', true) 698 .addClass('webform-disabled-flag'); 699 $texts 700 .val([action['argument']]) 701 .webformProp('readonly', true) 702 .addClass('webform-disabled-flag'); 703 // A special case is made for markup. It is sanitized with 704 // filter_xss_admin on the server. otherwise text() should be used 705 // to avoid an XSS vulnerability. text() however would preclude 706 // the use of tags like <strong> or <a>. 707 $markups.html(action['argument']); 708 } 709 else { 710 $selects.not('.webform-disabled-flag') 711 .webformProp('disabled', false); 712 $texts.not('.webform-disabled-flag') 713 .webformProp('readonly', false); 714 // Markup not set? Then restore original markup as provided in 715 // the attribute data-webform-markup. 716 $markups.each(function () { 717 var $this = $(this); 718 var original = $this.data('webform-markup'); 719 if (original !== undefined) { 720 $this.html(original); 721 } 722 }); 723 } 724 break; 725 } 726 }); // End look on each action for one conditional. 727 }); // End loop on each conditional. 728 729 $form.find('.webform-disabled-flag').removeClass('webform-disabled-flag'); 730 }; 731 732 /** 733 * Event handler to prevent propagation of events. 734 * 735 * Typically click for disabling radio and checkboxes. 736 */ 737 Drupal.webform.stopEvent = function () { 738 return false;
739 }; 740 741 Drupal.webform.conditionalOperatorStringEqual = function (element, existingValue, ruleValue) { 742 var returnValue = false; 743 var currentValue = Drupal.webform.stringValue(element, existingValue); 744 $.each(currentValue, function (n, value) { 745 if (value.toLowerCase() === ruleValue.toLowerCase()) { 746 returnValue = true; 747 return false; // break. 748 } 749 }); 750 return returnValue; 751 }; 752 753 Drupal.webform.conditionalOperatorStringNotEqual = function (element, existingValue, ruleValue) { 754 var found = false; 755 var currentValue = Drupal.webform.stringValue(element, existingValue); 756 $.each(currentValue, function (n, value) { 757 if (value.toLowerCase() === ruleValue.toLowerCase()) { 758 found = true; 759 } 760 }); 761 return !found; 762 }; 763 764 Drupal.webform.conditionalOperatorStringContains = function (element, existingValue, ruleValue) { 765 var returnValue = false; 766 var currentValue = Drupal.webform.stringValue(element, existingValue); 767 $.each(currentValue, function (n, value) { 768 if (value.toLowerCase().indexOf(ruleValue.toLowerCase()) > -1) { 769 returnValue = true; 770 return false; // break. 771 } 772 }); 773 return returnValue; 774 }; 775 776 Drupal.webform.conditionalOperatorStringDoesNotContain = function (element, existingValue, ruleValue) { 777 var found = false; 778 var currentValue = Drupal.webform.stringValue(element, existingValue); 779 $.each(currentValue, function (n, value) { 780 if (value.toLowerCase().indexOf(ruleValue.toLowerCase()) > -1) { 781 found = true; 782 } 783 }); 784 return !found; 785 }; 786 787 Drupal.webform.conditionalOperatorStringBeginsWith = function (element, existingValue, ruleValue) { 788 var returnValue = false; 789 var currentValue = Drupal.webform.stringValue(element, existingValue); 790 $.each(currentValue, function (n, value) { 791 if (value.toLowerCase().indexOf(ruleValue.toLowerCase()) === 0) { 792 returnValue = true; 793 return false; // break. 794 } 795 }); 796 return returnValue; 797 }; 798 799 Drupal.webform.conditionalOperatorStringEndsWith = function (element, existingValue, ruleValue) { 800 var returnValue = false; 801 var currentValue = Drupal.webform.stringValue(element, existingValue); 802 $.each(currentValue, function (n, value) { 803 if (value.toLowerCase().lastIndexOf(ruleValue.toLowerCase()) === value.length - ruleValue.length) { 804 returnValue = true; 805 return false; // break. 806 } 807 }); 808 return returnValue; 809 }; 810 811 Drupal.webform.conditionalOperatorStringEmpty = function (element, existingValue, ruleValue) { 812 var currentValue = Drupal.webform.stringValue(element, existingValue); 813 var returnValue = true; 814 $.each(currentValue, function (n, value) { 815 if (value !== '') { 816 returnValue = false; 817 return false; // break. 818 } 819 }); 820 return returnValue; 821 }; 822 823 Drupal.webform.conditionalOperatorStringNotEmpty = function (element, existingValue, ruleValue) { 824 return !Drupal.webform.conditionalOperatorStringEmpty(element, existingValue, ruleValue); 825 }; 826 827 Drupal.webform.conditionalOperatorSelectGreaterThan = function (element, existingValue, ruleValue) { 828 var currentValue = Drupal.webform.stringValue(element, existingValue); 829 return Drupal.webform.compare_select(currentValue[0], ruleValue, element) > 0; 830 }; 831 832 Drupal.webform.conditionalOperatorSelectGreaterThanEqual = function (element, existingValue, ruleValue) { 833 var currentValue = Drupal.webform.stringValue(element, existingValue); 834 var comparison = Drupal.webform.compare_select(currentValue[0], ruleValue, element); 835 return comparison > 0 || comparison === 0; 836 }; 837 838 Drupal.webform.conditionalOperatorSelectLessThan = function (element, existingValue, ruleValue) { 839 var currentValue = Drupal.webform.stringValue(element, existingValue); 840 return Drupal.webform.compare_select(currentValue[0], ruleValue, element) < 0; 841 }; 842 843 Drupal.webform.conditionalOperatorSelectLessThanEqual = function (element, existingValue, ruleValue) { 844 var currentValue = Drupal.webform.stringValue(element, existingV
844alue); 845 var comparison = Drupal.webform.compare_select(currentValue[0], ruleValue, element); 846 return comparison < 0 || comparison === 0; 847 }; 848 849 Drupal.webform.conditionalOperatorNumericEqual = function (element, existingValue, ruleValue) { 850 // See float comparison: http://php.net/manual/en/language.types.float.php 851 var currentValue = Drupal.webform.stringValue(element, existingValue); 852 var epsilon = 0.000001; 853 // An empty string does not match any number. 854 return currentValue[0] === '' ? false : (Math.abs(parseFloat(currentValue[0]) - parseFloat(ruleValue)) < epsilon); 855 }; 856 857 Drupal.webform.conditionalOperatorNumericNotEqual = function (element, existingValue, ruleValue) { 858 // See float comparison: http://php.net/manual/en/language.types.float.php 859 var currentValue = Drupal.webform.stringValue(element, existingValue); 860 var epsilon = 0.000001; 861 // An empty string does not match any number. 862 return currentValue[0] === '' ? true : (Math.abs(parseFloat(currentValue[0]) - parseFloat(ruleValue)) >= epsilon); 863 }; 864 865 Drupal.webform.conditionalOperatorNumericGreaterThan = function (element, existingValue, ruleValue) { 866 var currentValue = Drupal.webform.stringValue(element, existingValue); 867 return parseFloat(currentValue[0]) > parseFloat(ruleValue); 868 }; 869 870 Drupal.webform.conditionalOperatorNumericGreaterThanEqual = function (element, existingValue, ruleValue) { 871 return Drupal.webform.conditionalOperatorNumericGreaterThan(element, existingValue, ruleValue) || 872 Drupal.webform.conditionalOperatorNumericEqual(element, existingValue, ruleValue); 873 }; 874 875 Drupal.webform.conditionalOperatorNumericLessThan = function (element, existingValue, ruleValue) { 876 var currentValue = Drupal.webform.stringValue(element, existingValue); 877 return parseFloat(currentValue[0]) < parseFloat(ruleValue); 878 }; 879 880 Drupal.webform.conditionalOperatorNumericLessThanEqual = function (element, existingValue, ruleValue) { 881 return Drupal.webform.conditionalOperatorNumericLessThan(element, existingValue, ruleValue) || 882 Drupal.webform.conditionalOperatorNumericEqual(element, existingValue, ruleValue); 883 }; 884 885 Drupal.webform.conditionalOperatorDateEqual = function (element, existingValue, ruleValue) { 886 var currentValue = Drupal.webform.dateValue(element, existingValue); 887 return currentValue === ruleValue; 888 }; 889 890 Drupal.webform.conditionalOperatorDateNotEqual = function (element, existingValue, ruleValue) { 891 return !Drupal.webform.conditionalOperatorDateEqual(element, existingValue, ruleValue); 892 }; 893 894 Drupal.webform.conditionalOperatorDateBefore = function (element, existingValue, ruleValue) { 895 var currentValue = Drupal.webform.dateValue(element, existingValue); 896 return (currentValue !== false) && currentValue < ruleValue; 897 }; 898 899 Drupal.webform.conditionalOperatorDateBeforeEqual = function (element, existingValue, ruleValue) { 900 var currentValue = Drupal.webform.dateValue(element, existingValue); 901 return (currentValue !== false) && (currentValue < ruleValue || currentValue === ruleValue); 902 }; 903 904 Drupal.webform.conditionalOperatorDateAfter = function (element, existingValue, ruleValue) { 905 var currentValue = Drupal.webform.dateValue(element, existingValue); 906 return (currentValue !== false) && currentValue > ruleValue; 907 }; 908 909 Drupal.webform.conditionalOperatorDateAfterEqual = function (element, existingValue, ruleValue) { 910 var currentValue = Drupal.webform.dateValue(element, existingValue); 911 return (currentValue !== false) && (currentValue > ruleValue || currentValue === ruleValue); 912 }; 913 914 Drupal.webform.conditionalOperatorTimeEqual = function (element, existingValue, ruleValue) { 915 var currentValue = Drupal.webform.timeValue(element, existingValue); 916 return currentValue === ruleValue; 917 }; 918 919 Drupal.webform.conditionalOperatorTimeNotEqual = function (element, existingValue, ruleValue) { 920 return !Drupal.webform.conditionalOperatorTimeEqual(element, existingValue, ruleValue); 921 }; 922 923 Drupal.webform.conditionalOperatorTimeBefore = function (element, existingV
923alue, ruleValue) { 924 // Date and time operators intentionally exclusive for "before". 925 var currentValue = Drupal.webform.timeValue(element, existingValue); 926 return (currentValue !== false) && (currentValue < ruleValue); 927 }; 928 929 Drupal.webform.conditionalOperatorTimeBeforeEqual = function (element, existingValue, ruleValue) { 930 // Date and time operators intentionally exclusive for "before". 931 var currentValue = Drupal.webform.timeValue(element, existingValue); 932 return (currentValue !== false) && (currentValue < ruleValue || currentValue === ruleValue); 933 }; 934 935 Drupal.webform.conditionalOperatorTimeAfter = function (element, existingValue, ruleValue) { 936 // Date and time operators intentionally inclusive for "after". 937 var currentValue = Drupal.webform.timeValue(element, existingValue); 938 return (currentValue !== false) && (currentValue > ruleValue); 939 }; 940 941 Drupal.webform.conditionalOperatorTimeAfterEqual = function (element, existingValue, ruleValue) { 942 // Date and time operators intentionally inclusive for "after". 943 var currentValue = Drupal.webform.timeValue(element, existingValue); 944 return (currentValue !== false) && (currentValue > ruleValue || currentValue === ruleValue); 945 }; 946 947 /** 948 * Utility function to compare values of a select component. 949 * 950 * @param string a 951 * First select option key to compare 952 * @param string b 953 * Second select option key to compare 954 * @param array options 955 * Associative array where the a and b are within the keys 956 * 957 * @return integer based upon position of $a and $b in $options 958 * -N if $a above (<) $b 959 * 0 if $a = $b 960 * +N if $a is below (>) $b 961 */ 962 Drupal.webform.compare_select = function (a, b, element) { 963 var optionList = []; 964 $('option,input:radio,input:checkbox', element).each(function () { 965 optionList.push($(this).val()); 966 }); 967 var a_position = optionList.indexOf(a); 968 var b_position = optionList.indexOf(b); 969 return (a_position < 0 || b_position < 0) ? null : a_position - b_position; 970 }; 971 972 /** 973 * Utility to return current visibility. 974 * 975 * Uses actual visibility, except for hidden components which use the applied 976 * disabled class. 977 */ 978 Drupal.webform.isVisible = function ($element) { 979 return $element.hasClass('webform-component-hidden') 980 ? !$element.find('input').first().hasClass('webform-conditional-disabled') 981 : $element.closest('.webform-conditional-hidden').length == 0; 982 }; 983 984 /** 985 * Function to get a string value from a select/radios/text/etc. field. 986 */ 987 Drupal.webform.stringValue = function (element, existingValue) { 988 var value = []; 989 if (element) { 990 var $element = $(element); 991 if (Drupal.webform.isVisible($element)) { 992 // Checkboxes and radios. 993 $element.find('input[type=checkbox]:checked,input[type=radio]:checked').each(function () { 994 value.push(this.value); 995 }); 996 // Select lists. 997 if (!value.length) { 998 var selectValue = $element.find('select').val(); 999 if (selectValue) { 1000 if ($.isArray(selectValue)) { 1001 value = selectValue; 1002 } 1003 else { 1004 value.push(selectValue); 1005 } 1006 } 1007 } 1008 // Simple text fields. This check is done last so that the select list 1009 // in select-or-other fields comes before the "other" text field. 1010 if (!value.length) { 1011 $element.find('input:not([type=checkbox],[type=radio]),textarea').each(function () { 1012 value.push(this.value); 1013 }); 1014 } 1015 } 1016 } 1017 else { 1018 switch ($.type(existingValue)) { 1019 case 'array':
1020 value = existingValue; 1021 break; 1022 1023 case 'string': 1024 value.push(existingValue); 1025 break; 1026 } 1027 } 1028 return value; 1029 }; 1030 1031 /** 1032 * Utility function to calculate a second-based timestamp from a time field. 1033 */ 1034 Drupal.webform.dateValue = function (element, existingValue) { 1035 var value = false; 1036 if (element) { 1037 var $element = $(element); 1038 if (Drupal.webform.isVisible($element)) { 1039 var day = $element.find('[name*=day]').val(); 1040 var month = $element.find('[name*=month]').val(); 1041 var year = $element.find('[name*=year]').val(); 1042 // Months are 0 indexed in JavaScript. 1043 if (month) { 1044 month--; 1045 } 1046 if (year !== '' && month !== '' && day !== '') { 1047 value = Date.UTC(year, month, day) / 1000; 1048 } 1049 } 1050 } 1051 else { 1052 if ($.type(existingValue) === 'array' && existingValue.length) { 1053 existingValue = existingValue[0]; 1054 } 1055 if ($.type(existingValue) === 'string') { 1056 existingValue = existingV
1056alue.split('-'); 1057 } 1058 if (existingValue.length === 3) { 1059 value = Date.UTC(existingValue[0], existingValue[1], existingValue[2]) / 1000; 1060 } 1061 } 1062 return value; 1063 }; 1064 1065 /** 1066 * Utility function to calculate a millisecond timestamp from a time field. 1067 */ 1068 Drupal.webform.timeValue = function (element, existingValue) { 1069 var value = false; 1070 if (element) { 1071 var $element = $(element); 1072 if (Drupal.webform.isVisible($element)) { 1073 var hour = $element.find('[name*=hour]').val(); 1074 var minute = $element.find('[name*=minute]').val(); 1075 var ampm = $element.find('[name*=ampm]:checked').val(); 1076 1077 // Convert to integers if set. 1078 hour = (hour === '') ? hour : parseInt(hour); 1079 minute = (minute === '') ? minute : parseInt(minute); 1080 1081 if (hour !== '') { 1082 hour = (hour < 12 && ampm == 'pm') ? hour + 12 : hour; 1083 hour = (hour === 12 && ampm == 'am') ? 0 : hour; 1084 } 1085 if (hour !== '' && minute !== '') { 1086 value = Date.UTC(1970, 0, 1, hour, minute) / 1000; 1087 } 1088 } 1089 } 1090 else { 1091 if ($.type(existingValue) === 'array' && existingValue.length) {
1092 existingValue = existingValue[0]; 1093 } 1094 if ($.type(existingValue) === 'string') { 1095 existingValue = existingValue.split(':'); 1096 } 1097 if (existingValue.length >= 2) { 1098 value = Date.UTC(1970, 0, 1, existingValue[0], existingValue[1]) / 1000; 1099 } 1100 } 1101 return value; 1102 }; 1103 1104 /** 1105 * Make a prop shim for jQuery < 1.9. 1106 */ 1107 $.fn.webformProp = $.fn.webformProp || function (name, value) { 1108 if (value) { 1109 return $.fn.prop ? this.prop(name, true) : this.attr(name, true); 1110 } 1111 else { 1112 return $.fn.prop ? this.prop(name, false) : this.removeAttr(name); 1113 } 1114 }; 1115 1116 /** 1117 * Make a multi-valued val() function. 1118 * 1119 * This is for setting checkboxes, radios, and select elements. 1120 */ 1121 $.fn.webformVal = function (values) { 1122 this.each(function () { 1123 var $this = $(this); 1124 var value = $this.val(); 1125 var on = $.inArray($this.val(), values) != -1; 1126 if (this.nodeName == 'OPTION') { 1127 $this.webformProp('selected', on ? value : false); 1128 } 1129 else { 1130 $this.val(on ? [value] : false); 1131 } 1132 }); 1133 return this; 1134 }; 1135 1136 /** 1137 * Given a table's DOM element, restripe the odd/even classes. 1138 */ 1139 Drupal.webform.restripeTable = function (table) { 1140 // :even and :odd are reversed because jQuery counts from 0 and 1141 // we count from 1, so we're out of sync. 1142 // Match immediate children of the parent element to allow nesting. 1143 $('> tbody > tr, > tr', table) 1144 .filter(':visible:odd').filter('.odd') 1145 .removeClass('odd').addClass('even') 1146 .end().end() 1147 .filter(':visible:even').filter('.even') 1148 .removeClass('even').addClass('odd'); 1149 }; 1150 1151})(jQuery); 1152;
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.