[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/message/yui/build/moodle-core_message-messenger/ -> moodle-core_message-messenger.js (source)

   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('&nbsp;', '')
 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  });


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1