1 2(function ($) { 3 4Drupal.Nodejs = Drupal.Nodejs || { 5 'contentChannelNotificationCallbacks': {}, 6 'presenceCallbacks': {}, 7 'callbacks': {}, 8 'socket': false, 9 'connectionSetupHandlers': {} 10}; 11 12Drupal.behaviors.nodejs = { 13 attach: function (context, settings) { 14 if (!Drupal.Nodejs.socket) { 15 Drupal.Nodejs.connect(); 16 } 17 } 18}; 19 20Drupal.Nodejs.runCallbacks = function (message) { 21 // It's possible that this message originated from an ajax request from the 22 // client associated with this socket. 23 if (message.clientSocketId && message.clientSocketId == Drupal.Nodejs.socket.id) { 24 return; 25 } 26 27 if (message.callback) { 28 if (typeof message.callback == 'string') { 29 message.callback = [message.callback]; 30 } 31 $.each(message.callback, function () { 32 var callback = this; 33 if (Drupal.Nodejs.callbacks[callback] && $.isFunction(Drupal.Nodejs.callbacks[callback].callback)) { 34 try { 35 Drupal.Nodejs.callbacks[callback].callback(message); 36 } 37 catch (exception) {} 38 } 39 }); 40 } 41 else if (message.presenceNotification != undefined) {
42 $.each(Drupal.Nodejs.presenceCallbacks, function () { 43 if ($.isFunction(this.callback)) { 44 try { 45 this.callback(message); 46 } 47 catch (exception) {} 48 } 49 }); 50 } 51 else if (message.contentChannelNotification != undefined) { 52 $.each(Drupal.Nodejs.contentChannelNotificationCallbacks, function () { 53 if ($.isFunction(this.callback)) { 54 try { 55 this.callback(message); 56 } 57 catch (exception) {} 58 } 59 }); 60 } 61 else { 62 $.each(Drupal.Nodejs.callbacks, function () { 63 if ($.isFunction(this.callback)) { 64 try { 65 this.callback(message); 66 } 67 catch (exception) {} 68 } 69 }); 70 } 71}; 72 73Drupal.Nodejs.runSetupHandlers = function (type) { 74 $.each(Drupal.Nodejs.connectionSetupHandlers, function () { 75 if ($.isFunction(this[type])) { 76 try { 77 this[type](); 78 } 79 catch (exception) {} 80 } 81 }); 82}; 83 84Drupal.Nodejs.connect = function () { 85 var scheme = Drupal.settings.nodejs.client.secure ? 'https' : 'http', 86 url = scheme + '://' + Drupal.settings.nodejs.client.host + ':' + Drupal.settings.nodejs.client.port; 87 Drupal.settings.nodejs.connectTimeout = Drupal.settings.nodejs.connectTimeout || 5000; 88 if (typeof io === 'undefined') { 89 return false; 90 } 91 Drupal.Nodejs.socket = io.connect(url, {'connect timeout': Drupal.settings.nodejs.connectTimeout}); 92 Drupal.Nodejs.socket.on('connect', function() { 93 Drupal.Nodejs.sendAuthMessage(); 94 Drupal.Nodejs.runSetupHandlers('connect'); 95 if (Drupal.ajax != undefined) { 96 // Monkey-patch Drupal.ajax.prototype.beforeSerialize to auto-magically 97 // send sessionId for AJAX requests so we can exclude the current browser 98 // window from resulting notifications. We do this so that modules can hook 99 // in to other modules ajax requests without having to patch them. 100 Drupal.ajax.prototype.nodejsOriginalBeforeSerialize = Drupal.ajax.prototype.beforeSerialize; 101 Drupal.ajax.prototype.beforeSerialize = function(element_settings, options) { 102 options.data['nodejs_client_socket_id'] = Drupal.Nodejs.socket.id; 103 return this.nodejsOriginalBeforeSerialize(element_settings, options); 104 }; 105 } 106 }); 107 108 Drupal.Nodejs.socket.on('message', Drupal.Nodejs.runCallbacks); 109 110 Drupal.Nodejs.socket.on('disconnect', function() { 111 Drupal.Nodejs.runSetupHandlers('disconnect'); 112 if (Drupal.ajax != undefined) { 113 Drupal.ajax.prototype.beforeSerialize = Drupal.Nodejs.originalBeforeSerialize; 114 } 115 }); 116 setTimeout("Drupal.Nodejs.checkConnection()", Drupal.settings.nodejs.connectTimeout + 250); 117}; 118 119Drupal.Nodejs.checkConnection = function () { 120 if (!Drupal.Nodejs.socket.connected) { 121 Drupal.Nodejs.runSetupHandlers('connectionFailure'); 122 } 123}; 124 125Drupal.Nodejs.sendAuthMessage = function () { 126 var authMessage = { 127 authToken: Drupal.settings.nodejs.authToken, 128 contentTokens: Drupal.settings.nodejs.contentTokens 129 }; 130 Drupal.Nodejs.socket.emit('authenticate', authMessage); 131}; 132 133Drupal.Nodejs.joinTokenChannel = function (channel, contentToken) { 134 var message = { 135 channel: channel, 136 contentToken: contentToken 137 }; 138 Drupal.Nodejs.socket.emit('join-token-channel', message); 139}; 140 141})(jQuery); 142 143; 144(function ($) { 145 Drupal.drupalchat = Drupal.drupalchat || {}; 146 Drupal.drupalchat.removeDuplicates = function() { 147 var liText = '', liList = $('#chatpanel .subpanel ul li'), listForRemove = []; 148 $(liList).each(function () { 149 var text = $(this).text(); 150 if (liText.indexOf('|'+ text + '|') == -1) 151 liText += '|'+ text + '|'; 152 else 153 listForRemove.push($(this)); 154 }); 155 $(listForRemove).each(function(){ 156 $(this).remove(); 157 //drupalchat.online_users = drupalchat.online_users - 1; 158 jQuery('#chatpanel .online-count').html($('#chatpanel .subpanel ul > li').size()); 159 }); 160 }; 161 162 Drupal.drupalchat.processChatDataNodejs = function(data) { 163 var drupalchat_messages = data; 164 if (drupalchat_messages.message.length > 0) { 165 // Play new message sound effect 166 var obj = swfobject.getObjectById("drupalchatbeep"); 167 if (obj) { 168 obj.drupalchatbeep(); // e.g. an external interface call 169 } 170 } 171 value = data; 172 //Add div if required. 173 chatboxtitle = value.uid1; 174 if (jQuery("#chatbox_"+chatboxtitle).length <= 0) { 175 createChatBox(chatboxtitle, value.name, 1); 176 } 177 else if (jQuery("#chatbox_"+chatboxtitle+" .subpanel").is(':hidden')) { 178 if (jQuery("#chatbox_"+chatboxtitle).css('display') == 'none') { 179 jQuery("#chatbox_"+chatboxtitle).css('display','block'); 180 } 181 jQuery("#chatbox_"+chatboxtitle+" a:first").click(); //Toggle the subpanel to make active 182 jQuery("#chatbox_"+chatboxtitle+" .chatboxtextarea").focus(); 183 } 184 value.message = value.message.replace(/{{drupalchat_newline}}/g,"<br />"); 185 value.message = emotify(value.message); 186 if (jQuery("#chatbox_"+chatboxtitle+" .chatboxcontent .chatboxusername a:last").html() == value.name) { 187 jQuery("#chatbox_"+chatboxtitle+" .chatboxcontent").append('<p>'+value.message+'</p>'); 188 } 189 else { 190 var currentTime = new Date(); 191 var hours = currentTime.getHours(); 192 var minutes = currentTime.getMinutes(); 193 if (hours < 10) { 194 hours = "0" + hours; 195 } 196 if (minutes < 10) { 197 minutes = "0" + minutes; 198 } 199 jQuery("#chatbox_"+chatboxtitle+" .chatboxcontent").append('<div class="chatboxusername"><span class="chatboxtime">'+hours+':'+minutes+'</span><a href="'+Drupal.settings.basePath+'user/'+chatboxtitle+'">
199'+value.name+'</a></div><p>'+value.message+'</p>'); 200 } 201 jQuery("#chatbox_"+chatboxtitle+" .chatboxcontent").scrollTop(jQuery("#chatbox_"+chatboxtitle+" .chatboxcontent")[0].scrollHeight); 202 jQuery.titleAlert(Drupal.settings.drupalchat.newMessage, {requireBlur:true, stopOnFocus:true, interval:800}); 203 }; 204 205Drupal.drupalchat.processUserOnline = function(data){ 206 if(data.uid!=Drupal.settings.drupalchat.uid) { 207 if(jQuery("a #drupalchat_user_"+data.uid).length <= 0) { 208 jQuery('#chatpanel .subpanel ul > li.link').remove(); 209 jQuery('#chatpanel .subpanel ul').append('<li class="status-' + '1' + '"><a class="' + data.uid + '" href="#" id="drupalchat_user_' + data.uid + '">' + data.name + '</a></li>'); 210 //drupalchat.online_users = drupalchat.online_users + 1; 211 jQuery('#chatpanel .online-count').html($('#chatpanel .subpanel ul > li').size()); 212 } 213 } 214 Drupal.drupalchat.removeDuplicates(); 215}; 216 217Drupal.drupalchat.processUserOffline = function(data){ 218 if(data!=Drupal.settings.drupalchat.uid) { 219 if(jQuery("#drupalchat_user_"+data).length > 0) { 220 jQuery("#drupalchat_user_"+data).parent().remove(); 221 //drupalchat.online_users = drupalchat.online_users - 1; 222 jQuery('#chatpanel .online-count').html($('#chatpanel .subpanel ul > li').size()); 223 if($('#chatpanel .subpanel ul > li').size() == 0) 224 jQuery('#chatpanel .subpanel ul').empty(); 225 //jQuery('#chatpanel .subpanel ul').append(Drupal.settings.drupalchat.noUsers); 226 //drupalchat.online_users = 0; 227 } 228 } 229 Drupal.drupalchat.removeDuplicates(); 230}; 231Drupal.behaviors.drupalchat_nodejs = { 232 attach: function(context, settings) { 233 234 } 235} 236Drupal.Nodejs.callbacks.drupalchatNodejsMessageHandler = { 237 callback: function (message) { 238 switch (message.type) { 239 case 'newMessage': 240 Drupal.drupalchat.processChatDataNodejs(jQuery.parseJSON(message.data)); 241 break; 242 case 'userOnline': 243 Drupal.drupalchat.processUserOnline(message.data); 244 break; 245 case 'userOffline': 246 Drupal.drupalchat.processUserOffline(message.data); 247 break; 248 case 'createChannel': 249 jQuery.post(Drupal.settings.drupalchat.addUrl); 250 break; 251 } 252 } 253}; 254 255 256})(jQuery); 257 258; 259/** 260 * @file 261 * Taskbar JavaScript tools 262 */ 263(function ($) { 264Drupal.taskbar = Drupal.taskbar || {timers:{}}; 265Drupal.settings.taskbar = Drupal.settings.taskbar || {}; 266 267Drupal.behaviors.taskbar = { 268attach: function (context, settings) { 269 if (Drupal.settings.taskbar.suppress) { 270 // Sometimes taskbar_suppress(TRUE) is called too late. 271 return; 272 } 273 274 if (context == document) { 275 $('body').addClass('with-taskbar'); 276 if (Drupal.settings.taskbar.update) { 277 if (Drupal.settings.taskbar.update_method == 'ajax') { 278 setInterval('Drupal.taskbar.refresh()', Drupal.settings.taskbar.delay); 279 } 280 else { 281 Drupal.taskbar.polling(); 282 } 283 } 284 if (Drupal.settings.taskbar.click_close) { 285 $('body').click(function(e) { 286 // Only close when click outside the taskbar 287 if ($(e.target).parents('#taskbar').length == 0) { 288 Drupal.taskbar.closeAll($(), true); 289 } 290 }); 291 } 292 } 293 294 $('.taskbar-item').each(function() { 295 var T = $(this); 296 if (T.hasClass('taskbar-item-options-ajax')) { 297 if (T.find('.taskbar-item-extra').length == 0) { 298 T.append('<div class="taskbar-item-extra"></div>'); 299 } 300 T.find('.taskbar-item-content:not(.taskbar-processed)').addClass('taskbar-processed').click(function() { 301 T.toggleClass('taskbar-item-active'); 302 Drupal.taskbar.closeAll(T, false); 303 var name = T.attr('id').replace(/^taskbar-item-/, ''); 304 if (T.find('.taskbar-item-extra').is(':visible')) { 305 // If this item is auto refresh, cancel it then it is closed 306 if (Drupal.settings.taskbar.ajax_refresh[name]) { 307 if (Drupal.settings.taskbar.update_method == 'ajax') { 308 clearInterval(Drupal.taskbar.timers[name]); 309 } 310 else { 311 Drupal.taskbar.timers[name].abort(); 312 } 313 } 314 Drupal.taskbar.expandItem(T); 315 } 316 else { 317 T.find('.taskbar-item-extra').html('<div class="taskbar-item-loading"></div>'); 318 Drupal.taskbar.expandItem(T); 319 Drupal.taskbar.showItem(name); 320 // If this item is auto refresh, set a refresh period for its extra content 321 if (Drupal.settings.taskbar.ajax_refresh[name]) { 322 if (Drupal.settings.taskbar.update_method == 'ajax') { 323 Drupal.taskbar.timers[name] = setInterval(function() {Drupal.taskbar.showItem(name);}, Drupal.settings.taskbar.ajax_refresh[name]); 324 } 325 else { 326 Drupal.taskbar.pollingItem(name); 327 } 328 } 329 } 330 }); 331 } 332 else if (T.find('.taskbar-item-extra').length > 0) { 333 T.find('.taskbar-item-content:not(.taskbar-processed)').addClass('taskbar-processed').click(function() { 334 Drupal.taskbar.expandItem(T.toggleClass('taskbar-item-active')); 335 Drupal.taskbar.closeAll(T, false); 336 }); 337 } 338 T.find('.taskbar-item-titlebar:not(.taskbar-processed)').addClass('taskbar-processed').click(function() { 339 T.find('.taskbar-item-content').click(); 340 }); 341 }); 342} 343} 344 345Drupal.taskbar.expandItem = function(item) { 346 item 347 .find('.taskbar-item-extra') 348 .slideToggle('fast', function() { 349 item.trigger('taskbarItemShow'); 350 }); 351} 352 353Drupal.taskbar.closeAll = function(item, force) { 354 if (Drupal.settings.taskbar.auto_close || force) { 355 $('#taskbar .taskbar-item').not('#' + item.attr('id')).removeClass('taskbar-item-active').find('.taskbar-item-extra').hide(); 356 } 357} 358 359Drupal.taskbar.polling = function() { 360 $.ajax({ 361 url: Drupal.settings.basePath + 'taskbar/polling/status', 362 dataType: 'json', 363 error: function () { 364 //don't flood the servers on error, wait 10 seconds before retrying 365 setTimeout(Drupal.taskbar.polling, 10000); 366 }, 367 success: function (data) { 368 Drupal.taskbar.AJAXrespond(data); 369 Drupal.taskbar.polling(); 370 } 371 }); 372} 373 374Drupal.taskbar.refresh = function() { 375 $.ajax({ 376 url: Drupal.settings.basePath + 'taskbar/status', 377 dataType: 'json', 378 success: Drupal.taskbar.AJAXrespond 379 }); 380} 381 382Drupal.taskbar.showItem = function(name) { 383 $.ajax({ 384 url: Drupal.settings.taskbar.ajax_path + '/' + name + '?current_system_path=' + Drupal.settings.taskbar.current_system_path, 385 dataType: 'json', 386 success: Drupal.taskbar.AJAXrespond 387 }); 388} 389 390Drupal.taskbar.pollingItem = function(name) { 391 Drupal.taskbar.timers[name] = $.ajax({ 392 url: Drupal.settings.basePath + 'taskbar/polling/display/' + name, 393 dataType: 'json', 394 error: function () { 395 //don't flood the servers on error, wait 10 seconds before retrying 396 setTimeout(Drupal.taskbar.pollingItem, 10000); 397 }, 398 success: function (data) { 399 Drupal.taskbar.AJAXrespond(data); 400 Drupal.taskbar.pollingItem(name); 401 } 402 }); 403} 404 405// This is a subset of Ctools Ajax Responder commands 406Drupal.taskbar.AJAXrespond = function(data) { 407 $.each(data, function(i, item) { 408 if (item.command == 'html') { 409 $(item.selector).html(item.data); 410 } 411 else if (item.command == 'replace') { 412 $(item.selector).replaceWith(item.data); 413 } 414 Drupal.attachBehaviors($(item.selector)); 415 }); 416} 417})(jQuery); 418 419; 420(function ($) { 421 422Drupal.googleanalytics = {}; 423 424$(document).ready(function() { 425 426 // Attach mousedown, keyup, touchstart events to document only and catch 427 // clicks on all elements. 428 $(document.body).bind("mousedown keyup touchstart", function(event) { 429 430 // Catch the closest surrounding link of a clicked element. 431 $(event.target).closest("a,area").each(function() { 432 433 // Is the clicked URL internal? 434 if (Drupal.googleanalytics.isInternal(this.href)) { 435 // Skip 'click' tracking, if custom tracking events are bound. 436 if ($(this).is('.colorbox') && (Drupal.settings.googleanalytics.trackColorbox)) {
437 // Do nothing here. The custom event will handle all tracking. 438 //console.info("Click on .colorbox item has been detected."); 439 } 440 // Is download tracking activated and the file extension configured for download tracking? 441 else if (Drupal.settings.googleanalytics.trackDownload && Drupal.googleanalytics.isDownload(this.href)) { 442 // Download link clicked. 443 gtag('event', Drupal.googleanalytics.getDownloadExtension(this.href).toUpperCase(), { 444 event_category: 'Downloads', 445 event_label: Drupal.googleanalytics.getPageUrl(this.href), 446 transport_type: 'beacon' 447 }); 448 } 449 else if (Drupal.googleanalytics.isInternalSpecial(this.href)) { 450 // Keep the internal URL for Google Analytics website overlay intact. 451 // @todo: May require tracking ID 452 var target = this; 453 $.each(Drupal.settings.googleanalytics.account, function () { 454 gtag('config', this, { 455 page_path: Drupal.googleanalytics.getPageUrl(target.href), 456 transport_type: 'beacon' 457 }); 458 }); 459 } 460 } 461 else { 462 if (Drupal.settings.googleanalytics.trackMailto && $(this).is("a[href^='mailto:'],area[href^='mailto:']")) { 463 // Mailto link clicked. 464 gtag('event', 'Click', { 465 event_category: 'Mails', 466 event_label: this.href.substring(7), 467 transport_type: 'beacon' 468 }); 469 } 470 else if (Drupal.settings.googleanalytics.trackOutbound && this.href.match(/^\w+:\/\//i)) { 471 if (Drupal.settings.googleanalytics.trackDomainMode !== 2 || (Drupal.settings.googleanalytics.trackDomainMode === 2 && !Drupal.googleanalytics.isCrossDomain(this.hostname, Drupal.settings.googleanalytics.trackCrossDomains))) { 472 // External link clicked / No top-level cross domain clicked. 473 gtag('event', 'Click', { 474 event_category: 'Outbound links', 475 event_label: this.href, 476 transport_type: 'beacon' 477 }); 478 } 479 } 480 } 481 }); 482 }); 483 484 // Track hash changes as unique pageviews, if this option has been enabled. 485 if (Drupal.settings.googleanalytics.trackUrlFragments) { 486 window.onhashchange = function() { 487 $.each(Drupal.settings.googleanalytics.account, function () { 488 gtag('config', this, { 489 page_path: location.pathname + location.search + location.hash 490 }); 491 }); 492 }; 493 } 494 495 // Colorbox: This event triggers when the transition has completed and the 496 // newly loaded content has been revealed. 497 if (Drupal.settings.googleanalytics.trackColorbox) { 498 $(document).bind("cbox_complete", function () { 499 var href = $.colorbox.element().attr("href"); 500 if (href) { 501 $.each(Drupal.settings.googleanalytics.account, function () { 502 gtag('config', this, { 503 page_path: Drupal.googleanalytics.getPageUrl(href) 504 }); 505 }); 506 } 507 }); 508 } 509 510}); 511 512/** 513 * Check whether the hostname is part of the cross domains or not. 514 * 515 * @param string hostname 516 * The hostname of the clicked URL. 517 * @param array crossDomains 518 * All cross domain hostnames as JS array. 519 * 520 * @return boolean 521 */ 522Drupal.googleanalytics.isCrossDomain = function (hostname, crossDomains) { 523 /** 524 * jQuery < 1.6.3 bug: $.inArray crushes IE6 and Chrome if second argument is 525 * `null` or `undefined`, https://bugs.jquery.com/ticket/10076, 526 * https://github.com/jquery/jquery/commit/a839af034db2bd934e4d4fa6758a3fed8de74174 527 * 528 * @todo: Remove/Refactor in D8 529 */ 530 if (!crossDomains) { 531 return false; 532 } 533 else { 534 return $.inArray(hostname, crossDomains) > -1 ? true : false; 535 } 536}; 537 538/** 539 * Check whether this is a download URL or not. 540 * 541 * @param string url 542 * The web url to check. 543 * 544 * @return boolean 545 */ 546Drupal.googleanalytics.isDownload = function (url) { 547 var isDownload = new RegExp("\\.(" + Drupal.settings.googleanalytics.trackDownloadExtensions + ")([\?#].*)?$", "i"); 548 return isDownload.test(url); 549}; 550 551/** 552 * Check whether this is an absolute internal URL or not. 553 * 554 * @param string url 555 * The web url to check. 556 * 557 * @return boolean 558 */ 559Drupal.googleanalytics.isInternal = function (url) { 560 var isInternal = new RegExp("^(https?):\/\/" + window.location.host, "i"); 561 return isInternal.test(url); 562}; 563 564/** 565 * Check whether this is a special URL or not. 566 * 567 * URL types: 568 * - gotwo.module /go/* links. 569 * 570 * @param string url 571 * The web url to check. 572 * 573 * @return boolean 574 */ 575Drupal.googleanalytics.isInternalSpecial = function (url) { 576 var isInternalSpecial = new RegExp("(\/go\/.*)$", "i"); 577 return isInternalSpecial.test(url); 578}; 579 580/** 581 * Extract the relative internal URL from an absolute internal URL. 582 * 583 * Examples: 584 * - https://mydomain.com/node/1 -> /node/1 585 * - https://example.com/foo/bar -> https://example.com/foo/bar 586 * 587 * @param string url 588 * The web url to check. 589 * 590 * @return string 591 * Internal website URL 592 */ 593Drupal.googleanalytics.getPageUrl = function (url) { 594 var extractInternalUrl = new RegExp("^(https?):\/\/" + window.location.host, "i"); 595 return url.replace(extractInternalUrl, ''); 596}; 597 598/** 599 * Extract the download file extension from the URL. 600 * 601 * @param string url 602 * The web url to check. 603 * 604 * @return string 605 * The file extension of the passed url. e.g. "zip", "txt" 606 */ 607Drupal.googleanalytics.getDownloadExtension = function (url) { 608 var extractDownloadextension = new RegExp("\\.(" + Drupal.settings.googleanalytics.trackDownloadExtensions + ")([\?#].*)?$", "i"); 609 var extension = extractDownloadextension.exec(url); 610 return (extension === null) ? '' : extension[1]; 611}; 612 613})(jQuery); 614;
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.