[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 YUI.add('moodle-core_message-messenger', function (Y, NAME) { 2 3 // This file is part of Moodle - http://moodle.org/ 4 // 5 // Moodle is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // Moodle is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 // 15 // You should have received a copy of the GNU General Public License 16 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 17 /* eslint-disable no-unused-vars */ 18 19 /** 20 * Messenger constants. 21 * 22 * @module moodle-core_message-messenger 23 * @package core_message 24 * @copyright 2015 Frédéric Massart - FMCorz.net 25 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 26 */ 27 28 29 /** 30 * Cascading Style Sheet References. 31 * 32 * Using the name "CSS" would redefine the existing JS object CSS. 33 * 34 * @type {Object} 35 */ 36 var CSSR = {}; 37 38 /** 39 * Object containing a reference to the selectors. 40 * 41 * @type {Object} 42 */ 43 var SELECTORS = {}; 44 // This file is part of Moodle - http://moodle.org/ 45 // 46 // Moodle is free software: you can redistribute it and/or modify 47 // it under the terms of the GNU General Public License as published by 48 // the Free Software Foundation, either version 3 of the License, or 49 // (at your option) any later version. 50 // 51 // Moodle is distributed in the hope that it will be useful, 52 // but WITHOUT ANY WARRANTY; without even the implied warranty of 53 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 54 // GNU General Public License for more details. 55 // 56 // You should have received a copy of the GNU General Public License 57 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 58 /* global SELECTORS */ 59 60 /** 61 * Messenger manager. 62 * 63 * @module moodle-core_message-messenger 64 * @package core_message 65 * @copyright 2015 Frédéric Massart - FMCorz.net 66 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 67 */ 68 69 SELECTORS.MANAGER = { 70 SENDMESSAGE: '[data-trigger="core_message-messenger::sendmessage"]' 71 }; 72 73 /** 74 * Messenger manager. 75 * 76 * @namespace M.core_message.messenger 77 * @class MANAGER 78 * @constructor 79 */ 80 var MANAGER = function() { 81 MANAGER.superclass.constructor.apply(this, arguments); 82 }; 83 Y.namespace('M.core_message.messenger').Manager = Y.extend(MANAGER, Y.Base, { 84 85 _sendMessageDialog: null, 86 _events: [], 87 88 /** 89 * Initializer. 90 * 91 * @method initializer 92 */ 93 initializer: function() { 94 this._setEvents(); 95 }, 96 97 /** 98 * Sending a message. 99 * 100 * @method sendMessage 101 * @param {Number} userid The user ID to send a message to. 102 * @param {String} fullname The fullname of the user. 103 * @param {EventFacade} e The event triggered, when any it should be passed to the dialog. 104 */ 105 sendMessage: function(userid, fullname, e) { 106 var Klass; 107 if (!this._sendMessageDialog) { 108 Klass = Y.namespace('M.core_message.messenger.sendMessage'); 109 this._sendMessageDialog = new Klass({ 110 url: this.get('url') 111 }); 112 } 113 114 this._sendMessageDialog.prepareForUser(userid, fullname); 115 this._sendMessageDialog.show(e); 116 }, 117 118 /** 119 * Pop up an alert dialogue to notify the logged in user that they are blocked from 120 * messaging the target user. 121 * 122 * @method alertBlocked 123 * @param {String} blockedString The identifier to retrieve the blocked user message. 124 * @param {String} fullName The target user's full name. 125 */ 126 alertBlocked: function(blockedString, fullName) { 127 new M.core.alert({ 128 title: M.util.get_string('error', 'core'), 129 message: M.util.get_string(blockedString, 'message', fullName) 130 }); 131 }, 132 133 /** 134 * Register the events. 135 * 136 * @method _setEvents. 137 */ 138 _setEvents: function() { 139 var captureEvent = function(e) { 140 var target = e.currentTarget, 141 userid = parseInt(target.getData('userid'), 10), 142 fullname = target.getData('fullname'), 143 blockedString = target.getData('blocked-string'); 144 145 if (!userid || !fullname) { 146 return; 147 } 148 149 // Pass the validation before preventing defaults. 150 e.preventDefault(); 151 if (blockedString) { 152 this.alertBlocked(blockedString, fullname); 153 } else { 154 this.sendMessage(userid, fullname, e); 155 } 156 }; 157 158 this._events.push(Y.delegate('click', captureEvent, 'body', SELECTORS.MANAGER.SENDMESSAGE, this)); 159 this._events.push(Y.one(Y.config.doc).delegate('key', captureEvent, 'space', SELECTORS.MANAGER.SENDMESSAGE, this)); 160 } 161 162 }, { 163 NAME: 'core_message-messenger-manager', 164 ATTRS: { 165 166 /** 167 * URL to the message Ajax actions. 168 * 169 * @attribute url 170 * @default M.cfg.wwwroot + '/message/ajax.php' 171 * @type String 172 */ 173 url: { 174 readonly: true, 175 value: M.cfg.wwwroot + '/message/ajax.php' 176 } 177 } 178 }); 179 180 var MANAGERINST; 181 Y.namespace('M.core_message.messenger').init = function(config) { 182 if (!MANAGERINST) { 183 // Prevent duplicates of the manager if this function is called more than once. 184 MANAGERINST = new MANAGER(config); 185 } 186 return MANAGERINST; 187 }; 188 // This file is part of Moodle - http://moodle.org/ 189 // 190 // Moodle is free software: you can redistribute it and/or modify 191 // it under the terms of the GNU General Public License as published by 192 // the Free Software Foundation, either version 3 of the License, or 193 // (at your option) any later version. 194 // 195 // Moodle is distributed in the hope that it will be useful, 196 // but WITHOUT ANY WARRANTY; without even the implied warranty of 197 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 198 // GNU General Public License for more details. 199 // 200 // You should have received a copy of the GNU General Public License 201 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 202 /* global CSSR, SELECTORS */ 203 204 /** 205 * Send message dialog. 206 * 207 * @module moodle-core_message-messenger 208 * @package core_message 209 * @copyright 2015 Frédéric Massart - FMCorz.net 210 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 211 */ 212 213 CSSR.SENDMSGDIALOG = { 214 ACCESSHIDE: 'accesshide', 215 ACTIONS: 'message-actions', 216 FOOTER: 'message-footer', 217 HIDDEN: 'hidden', 218 HISTORYLINK: 'message-history', 219 INPUT: 'message-input', 220 INPUTAREA: 'message-area', 221 NOTICE: 'message-notice', 222 NOTICEAREA: 'message-notice-area', 223 PREFIX: 'core_message-messenger-sendmessage', 224 SENDBTN: 'message-send', 225 WRAPPER: 'message-wrapper' 226 }; 227 228 SELECTORS.SENDMSGDIALOG = { 229 FORM: 'form', 230 HISTORYLINK: '.message-history', 231 INPUT: '.message-input', 232 NOTICE: '.message-notice div', 233 NOTICEAREA: '.message-notice-area', 234 SENDBTN: '.message-send' 235 }; 236 237 /** 238 * Send message dialog. 239 * 240 * @namespace M.core_message 241 * @class SENDMSGDIALOG 242 * @constructor 243 */ 244 var SENDMSGDIALOG = function() { 245 SENDMSGDIALOG.superclass.constructor.apply(this, arguments); 246 }; 247 Y.namespace('M.core_message.messenger').sendMessage = Y.extend(SENDMSGDIALOG, M.core.dialogue, { 248 249 _bb: null, 250 _sendLock: false, 251 _hide: null, 252 /** 253 * Initializer. 254 * 255 * @method initializer 256 */ 257 initializer: function() { 258 var tpl, 259 content; 260 261 this._bb = this.get('boundingBox'); 262 this._hide = this.hide; 263 264 // Prepare the content area. 265 tpl = Y.Handlebars.compile( 266 '<form action="#" id="messageform">' + 267 '<div class="{{CSSR.INPUTAREA}}">' + 268 '<label class="{{CSSR.ACCESSHIDE}}" for="{{id}}">{{labelStr}}</label>' + 269 '<textarea class="{{CSSR.INPUT}}" id="{{id}}"></textarea>' + 270 '<div class="{{CSSR.NOTICEAREA}}" style="display: none;" aria-live="assertive">' + 271 '<div class="{{CSSR.NOTICE}}"><div></div></div>' + 272 '</div>' + 273 '</div>' + 274 '<div class="{{CSSR.ACTIONS}}">' + 275 '<input type="submit" value="{{sendStr}}" class="{{CSSR.SENDBTN}}">' + 276 '<a href="#" class="{{CSSR.HISTORYLINK}}">{{viewHistoryStr}}</a>' + 277 '<div style="clear: both;"></div>' + 278 '</div>' + 279 '</form>' 280 ); 281 content = Y.Node.create( 282 tpl({ 283 CSSR: CSSR.SENDMSGDIALOG, 284 id: Y.guid(), 285 labelStr: M.util.get_string('messagetosend', 'core_message'), 286 loadingIcon: M.util.image_url('i/loading', 'moodle'), 287 sendStr: M.util.get_string('sendmessage', 'core_message'), 288 viewHistoryStr: M.util.get_string('viewconversation', 'core_message') 289 }) 290 ); 291 this.setStdModContent(Y.WidgetStdMod.BODY, content, Y.WidgetStdMod.REPLACE); 292 293 // Use standard dialogue class name. This removes the default styling of the footer. 294 this._bb.one('.moodle-dialogue-wrap').addClass('moodle-dialogue-content'); 295 296 // Set the events listeners. 297 this._setEvents(); 298 }, 299 300 /** 301 * Prepare the dialog for a user. 302 * 303 * @method prepareForUser 304 * @param {Number} userid The user ID. 305 * @param {String} fullname The user full name. 306 */ 307 prepareForUser: function(userid, fullname) { 308 var title; 309 310 this.set('userid', userid); 311 this.set('fullname', fullname); 312 313 // Prepare the title. 314 title = Y.Node.create('<h1>' + Y.Escape.html(fullname) + '</h1>'); 315 this.setStdModContent(Y.WidgetStdMod.HEADER, title, Y.WidgetStdMod.REPLACE); 316 317 // Update the link to the conversation. 318 this._bb.one(SELECTORS.SENDMSGDIALOG.HISTORYLINK) 319 .set('href', M.cfg.wwwroot + '/message/index.php?id=' + this.get('userid')); 320 321 // Set the content as empty and lock send. 322 this._bb.one(SELECTORS.SENDMSGDIALOG.INPUT).set('value', ''); 323 324 // Register form with formchangechecker 325 Y.use('moodle-core-formchangechecker', function() { 326 M.core_formchangechecker.init({formid: "messageform"}); 327 }); 328 }, 329 330 /** 331 * Send the message to the user. 332 * 333 * @method sendMessage 334 * @param {String} message The message to be sent. 335 */ 336 sendMessage: function(message) { 337 if (this._sendLock) { 338 // Do not proceed if the lock is active. 339 return; 340 } 341 342 if (!message || !this._validateMessage(message)) { 343 // Do not send falsy messages. 344 return; 345 } 346 347 // Actually send the message. 348 this._ioSend = Y.io(this.get('url'), { 349 method: 'POST', 350 data: { 351 sesskey: M.cfg.sesskey, 352 action: 'sendmessage', 353 userid: this.get('userid'), 354 message: message 355 }, 356 on: { 357 start: function() { 358 var img = '<img alt="" role="presentation" src="' + M.util.image_url('i/loading_small', 'moodle') + '">'; 359 this.setSendLock(true); 360 this.showNotice(img + ' ' + M.util.get_string('sendingmessage', 'core_message')); 361 }, 362 success: function(id, response) { 363 var data = null; 364 365 try { 366 data = Y.JSON.parse(response.responseText); 367 if (data.error) { 368 this.hideNotice(); 369 new M.core.ajaxException(data); 370 return; 371 } 372 } catch (e) { 373 this.hideNotice(); 374 new M.core.exception(e); 375 return; 376 } 377 378 // Show a success message. 379 this.showNotice(M.util.get_string('messagesent', 'core_message')); 380 381 // Hide the dialog. 382 Y.later(1300, this, function() { 383 this.setSendLock(false); 384 this.hideNotice(); 385 this.hide(); 386 }); 387 }, 388 failure: function() { 389 this.setSendLock(false); 390 this.hideNotice(); 391 new M.core.alert({ 392 title: M.util.get_string('error', 'core'), 393 message: M.util.get_string('errorwhilesendingmessage', 'core_message') 394 }); 395 } 396 }, 397 context: this 398 }); 399 }, 400 401 /** 402 * Override the default hide function. 403 * @method hide 404 */ 405 hide: function() { 406 var self = this; 407 408 if (!M.core_formchangechecker.get_form_dirty_state()) { 409 return SENDMSGDIALOG.superclass.hide.call(this, arguments); 410 } 411 412 Y.use('moodle-core-notification-confirm', function() { 413 var confirm = new M.core.confirm({ 414 title: M.util.get_string('confirm', 'moodle'), 415 question: M.util.get_string('changesmadereallygoaway', 'moodle'), 416 yesLabel: M.util.get_string('confirm', 'moodle'), 417 noLabel: M.util.get_string('cancel', 'moodle') 418 }); 419 confirm.on('complete-yes', function() { 420 M.core_formchangechecker.reset_form_dirty_state(); 421 confirm.hide(); 422 confirm.destroy(); 423 return SENDMSGDIALOG.superclass.hide.call(this, arguments); 424 }, self); 425 }); 426 }, 427 428 /** 429 * Show a notice. 430 * 431 * @method hideNotice. 432 */ 433 hideNotice: function() { 434 this._bb.one(SELECTORS.SENDMSGDIALOG.NOTICEAREA).hide(); 435 }, 436 437 /** 438 * Show a notice. 439 * 440 * @param {String} html String to show. 441 * @method showNotice. 442 */ 443 showNotice: function(html) { 444 this._bb.one(SELECTORS.SENDMSGDIALOG.NOTICE).setHTML(html); 445 this._bb.one(SELECTORS.SENDMSGDIALOG.NOTICEAREA).show(); 446 }, 447 448 /** 449 * Set the send lock. 450 * 451 * We do not lock the send button because that would cause a focus change on screenreaders 452 * which then conflicts with the aria-live region reading out that we are sending a message. 453 * 454 * @method setSendLock 455 * @param {Boolean} lock When true, enables the lock. 456 */ 457 setSendLock: function(lock) { 458 if (lock) { 459 this._sendLock = true; 460 } else { 461 this._sendLock = false; 462 } 463 }, 464 465 /** 466 * Register the events. 467 * 468 * @method _setEvents. 469 */ 470 _setEvents: function() { 471 // Form submit. 472 this._bb.one(SELECTORS.SENDMSGDIALOG.FORM).on('submit', function(e) { 473 var message = this._bb.one(SELECTORS.SENDMSGDIALOG.INPUT).get('value'); 474 e.preventDefault(); 475 this.sendMessage(message); 476 }, this); 477 }, 478 479 /** 480 * Validates a message. 481 * 482 * @method _validateMessage 483 * @param {String} message A message to be validated. 484 */ 485 _validateMessage: function(message) { 486 var trimmed; 487 if (!message) { 488 return false; 489 } 490 491 // Basic validation. 492 trimmed = message.replace(' ', '') 493 .replace(' ', '') 494 .replace(/(<br\s*\/?>(<\/br\s*\/?>)?)+/, '') 495 .trim(); 496 497 return trimmed.length > 1; 498 } 499 500 }, { 501 NAME: 'core_message-messenger-sendmessage', 502 CSS_PREFIX: CSSR.SENDMSGDIALOG.PREFIX, 503 ATTRS: { 504 505 /** 506 * Fullname of the user. 507 * 508 * @attribute fullname 509 * @default '' 510 * @type String 511 */ 512 fullname: { 513 validator: Y.Lang.isString, 514 value: '' 515 }, 516 517 /** 518 * URL to the message Ajax actions. 519 * 520 * @attribute url 521 * @default null 522 * @type String 523 */ 524 url: { 525 validator: Y.Lang.isString, 526 value: null 527 }, 528 529 /** 530 * User ID this dialog interacts with. 531 * 532 * @attribute userid 533 * @default 0 534 * @type Number 535 */ 536 userid: { 537 validator: Y.Lang.isNumber, 538 value: 0 539 } 540 } 541 }); 542 543 Y.Base.modifyAttrs(Y.namespace('M.core_message.messenger.sendMessage'), { 544 545 /** 546 * List of extra classes. 547 * 548 * @attribute extraClasses 549 * @default ['core_message-messenger-sendmessage'] 550 * @type Array 551 */ 552 extraClasses: { 553 value: ['core_message-messenger-sendmessage'] 554 }, 555 556 /** 557 * Whether to focus on the target that caused the Widget to be shown. 558 * 559 * @attribute focusOnPreviousTargetAfterHide 560 * @default true 561 * @type Node 562 */ 563 focusOnPreviousTargetAfterHide: { 564 value: true 565 }, 566 567 /** 568 * 569 * Width. 570 * 571 * @attribute width 572 * @default '260px' 573 * @type String|Number 574 */ 575 width: { 576 value: '360px' 577 }, 578 579 /** 580 * Boolean indicating whether or not the Widget is visible. 581 * 582 * @attribute visible 583 * @default false 584 * @type Boolean 585 */ 586 visible: { 587 value: false 588 }, 589 590 /** 591 * Whether the widget should be modal or not. 592 * 593 * @attribute modal 594 * @type Boolean 595 * @default true 596 */ 597 modal: { 598 value: true 599 }, 600 601 /** 602 * Whether the widget should be draggable or not. 603 * 604 * @attribute draggable 605 * @type Boolean 606 * @default false 607 */ 608 draggable: { 609 value: false 610 }, 611 612 /** 613 * Whether to display the dialogue centrally on the screen. 614 * 615 * @attribute center 616 * @type Boolean 617 * @default false 618 */ 619 center: { 620 value: true 621 } 622 623 }); 624 625 626 }, '@VERSION@', { 627 "requires": [ 628 "escape", 629 "handlebars", 630 "io-base", 631 "moodle-core-notification-ajaxexception", 632 "moodle-core-notification-alert", 633 "moodle-core-notification-dialogue", 634 "moodle-core-notification-exception" 635 ] 636 });
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |