[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/mod/quiz/yui/build/moodle-mod_quiz-util-slot/ -> moodle-mod_quiz-util-slot-debug.js (source)

   1  YUI.add('moodle-mod_quiz-util-slot', function (Y, NAME) {
   2  
   3  /**
   4   * A collection of utility classes for use with slots.
   5   *
   6   * @module moodle-mod_quiz-util
   7   * @submodule moodle-mod_quiz-util-slot
   8   */
   9  
  10  Y.namespace('Moodle.mod_quiz.util.slot');
  11  
  12  /**
  13   * A collection of utility classes for use with slots.
  14   *
  15   * @class Moodle.mod_quiz.util.slot
  16   * @static
  17   */
  18  Y.Moodle.mod_quiz.util.slot = {
  19      CSS: {
  20          SLOT: 'slot',
  21          QUESTIONTYPEDESCRIPTION: 'qtype_description',
  22          CANNOT_DEPEND: 'question_dependency_cannot_depend'
  23      },
  24      CONSTANTS: {
  25          SLOTIDPREFIX: 'slot-',
  26          QUESTION: M.util.get_string('question', 'moodle')
  27      },
  28      SELECTORS: {
  29          SLOT: 'li.slot',
  30          INSTANCENAME: '.instancename',
  31          NUMBER: 'span.slotnumber',
  32          PAGECONTENT: 'div#page-content',
  33          PAGEBREAK: 'span.page_split_join_wrapper',
  34          ICON: 'img.smallicon',
  35          QUESTIONTYPEDESCRIPTION: '.qtype_description',
  36          SECTIONUL: 'ul.section',
  37          DEPENDENCY_WRAPPER: '.question_dependency_wrapper',
  38          DEPENDENCY_LINK: '.question_dependency_wrapper .cm-edit-action',
  39          DEPENDENCY_ICON: '.question_dependency_wrapper img'
  40      },
  41  
  42      /**
  43       * Retrieve the slot item from one of it's child Nodes.
  44       *
  45       * @method getSlotFromComponent
  46       * @param slotcomponent {Node} The component Node.
  47       * @return {Node|null} The Slot Node.
  48       */
  49      getSlotFromComponent: function(slotcomponent) {
  50          return Y.one(slotcomponent).ancestor(this.SELECTORS.SLOT, true);
  51      },
  52  
  53      /**
  54       * Determines the slot ID for the provided slot.
  55       *
  56       * @method getId
  57       * @param slot {Node} The slot to find an ID for.
  58       * @return {Number|false} The ID of the slot in question or false if no ID was found.
  59       */
  60      getId: function(slot) {
  61          // We perform a simple substitution operation to get the ID.
  62          var id = slot.get('id').replace(
  63                  this.CONSTANTS.SLOTIDPREFIX, '');
  64  
  65          // Attempt to validate the ID.
  66          id = parseInt(id, 10);
  67          if (typeof id === 'number' && isFinite(id)) {
  68              return id;
  69          }
  70          return false;
  71      },
  72  
  73      /**
  74       * Determines the slot name for the provided slot.
  75       *
  76       * @method getName
  77       * @param slot {Node} The slot to find a name for.
  78       * @return {string|false} The name of the slot in question or false if no ID was found.
  79       */
  80      getName: function(slot) {
  81          var instance = slot.one(this.SELECTORS.INSTANCENAME);
  82          if (instance) {
  83              return instance.get('firstChild').get('data');
  84          }
  85          return null;
  86      },
  87  
  88      /**
  89       * Determines the slot number for the provided slot.
  90       *
  91       * @method getNumber
  92       * @param slot {Node} The slot to find the number for.
  93       * @return {Number|false} The number of the slot in question or false if no number was found.
  94       */
  95      getNumber: function(slot) {
  96          if (!slot) {
  97              return false;
  98          }
  99          // We perform a simple substitution operation to get the number.
 100          var number = slot.one(this.SELECTORS.NUMBER).get('text').replace(
 101                          this.CONSTANTS.QUESTION, '');
 102          // Attempt to validate the ID.
 103          number = parseInt(number, 10);
 104          if (typeof number === 'number' && isFinite(number)) {
 105              return number;
 106          }
 107          return false;
 108      },
 109  
 110      /**
 111       * Updates the slot number for the provided slot.
 112       *
 113       * @method setNumber
 114       * @param slot {Node} The slot to update the number for.
 115       * @return void
 116       */
 117      setNumber: function(slot, number) {
 118          var numbernode = slot.one(this.SELECTORS.NUMBER);
 119          numbernode.setHTML('<span class="accesshide">' + this.CONSTANTS.QUESTION + '</span> ' + number);
 120      },
 121  
 122      /**
 123       * Returns a list of all slot elements on the page.
 124       *
 125       * @method getSlots
 126       * @return {node[]} An array containing slot nodes.
 127       */
 128      getSlots: function() {
 129          return Y.all(this.SELECTORS.PAGECONTENT + ' ' + this.SELECTORS.SECTIONUL + ' ' + this.SELECTORS.SLOT);
 130      },
 131  
 132      /**
 133       * Returns a list of all slot elements on the page that have numbers. Excudes description questions.
 134       *
 135       * @method getSlots
 136       * @return {node[]} An array containing slot nodes.
 137       */
 138      getNumberedSlots: function() {
 139          var selector = this.SELECTORS.PAGECONTENT + ' ' + this.SELECTORS.SECTIONUL;
 140              selector += ' ' + this.SELECTORS.SLOT + ':not(' + this.SELECTORS.QUESTIONTYPEDESCRIPTION + ')';
 141          return Y.all(selector);
 142      },
 143  
 144      /**
 145       * Returns the previous slot to the given slot.
 146       *
 147       * @method getPrevious
 148       * @param slot Slot node
 149       * @return {node|false} The previous slot node or false.
 150       */
 151      getPrevious: function(slot) {
 152          return slot.previous(this.SELECTORS.SLOT);
 153      },
 154  
 155      /**
 156       * Returns the previous numbered slot to the given slot.
 157       *
 158       * Ignores slots containing description question types.
 159       *
 160       * @method getPrevious
 161       * @param slot Slot node
 162       * @return {node|false} The previous slot node or false.
 163       */
 164      getPreviousNumbered: function(slot) {
 165          var previous = slot.previous(this.SELECTORS.SLOT + ':not(' + this.SELECTORS.QUESTIONTYPEDESCRIPTION + ')');
 166          if (previous) {
 167              return previous;
 168          }
 169  
 170          var section = slot.ancestor('li.section').previous('li.section');
 171          while (section) {
 172              var questions = section.all(this.SELECTORS.SLOT + ':not(' + this.SELECTORS.QUESTIONTYPEDESCRIPTION + ')');
 173              if (questions.size() > 0) {
 174                  return questions.item(questions.size() - 1);
 175              }
 176              section = section.previous('li.section');
 177          }
 178          return false;
 179      },
 180  
 181      /**
 182       * Reset the order of the numbers given to each slot.
 183       *
 184       * @method reorderSlots
 185       * @return void
 186       */
 187      reorderSlots: function() {
 188          // Get list of slot nodes.
 189          var slots = this.getSlots();
 190          // Loop through slots incrementing the number each time.
 191          slots.each(function(slot) {
 192  
 193              if (!Y.Moodle.mod_quiz.util.page.getPageFromSlot(slot)) {
 194                  // Move the next page to the front.
 195                  var nextpage = slot.next(Y.Moodle.mod_quiz.util.page.SELECTORS.PAGE);
 196                  slot.swap(nextpage);
 197              }
 198  
 199              var previousSlot = this.getPreviousNumbered(slot),
 200                  previousslotnumber = 0;
 201              if (slot.hasClass(this.CSS.QUESTIONTYPEDESCRIPTION)) {
 202                  return;
 203              }
 204  
 205              if (previousSlot) {
 206                  previousslotnumber = this.getNumber(previousSlot);
 207              }
 208  
 209              // Set slot number.
 210              this.setNumber(slot, previousslotnumber + 1);
 211          }, this);
 212      },
 213  
 214      /**
 215       * Add class only-has-one-slot to those sections that need it.
 216       *
 217       * @method updateOneSlotSections
 218       * @return void
 219       */
 220      updateOneSlotSections: function() {
 221          Y.all('.mod-quiz-edit-content ul.slots li.section').each(function(section) {
 222              if (section.all(this.SELECTORS.SLOT).size() > 1) {
 223                  section.removeClass('only-has-one-slot');
 224              } else {
 225                  section.addClass('only-has-one-slot');
 226              }
 227          }, this);
 228      },
 229  
 230      /**
 231       * Remove a slot and related elements from the list of slots.
 232       *
 233       * @method remove
 234       * @param slot Slot node
 235       * @return void
 236       */
 237      remove: function(slot) {
 238          var page = Y.Moodle.mod_quiz.util.page.getPageFromSlot(slot);
 239          slot.remove();
 240          // Is the page empty.
 241          if (!Y.Moodle.mod_quiz.util.page.isEmpty(page)) {
 242              return;
 243          }
 244          // If so remove it. Including add menu and page break.
 245          Y.Moodle.mod_quiz.util.page.remove(page);
 246      },
 247  
 248      /**
 249       * Returns a list of all page break elements on the page.
 250       *
 251       * @method getPageBreaks
 252       * @return {node[]} An array containing page break nodes.
 253       */
 254      getPageBreaks: function() {
 255          var selector = this.SELECTORS.PAGECONTENT + ' ' + this.SELECTORS.SECTIONUL;
 256              selector += ' ' + this.SELECTORS.SLOT + this.SELECTORS.PAGEBREAK;
 257          return Y.all(selector);
 258      },
 259  
 260      /**
 261       * Retrieve the page break element item from the given slot.
 262       *
 263       * @method getPageBreak
 264       * @param slot Slot node
 265       * @return {Node|null} The Page Break Node.
 266       */
 267      getPageBreak: function(slot) {
 268          return Y.one(slot).one(this.SELECTORS.PAGEBREAK);
 269      },
 270  
 271      /**
 272       * Add a page break and related elements to the list of slots.
 273       *
 274       * @method addPageBreak
 275       * @param beforenode Int | Node | HTMLElement | String to add
 276       * @return pagebreak PageBreak node
 277       */
 278      addPageBreak: function(slot) {
 279          var nodetext = M.mod_quiz.resource_toolbox.get('config').addpageiconhtml;
 280          nodetext = nodetext.replace('%%SLOT%%', this.getNumber(slot));
 281          var pagebreak = Y.Node.create(nodetext);
 282          slot.one('div').insert(pagebreak, 'after');
 283          return pagebreak;
 284      },
 285  
 286      /**
 287       * Remove a pagebreak from the given slot.
 288       *
 289       * @method removePageBreak
 290       * @param slot Slot node
 291       * @return boolean
 292       */
 293      removePageBreak: function(slot) {
 294          var pagebreak = this.getPageBreak(slot);
 295          if (!pagebreak) {
 296              return false;
 297          }
 298          pagebreak.remove();
 299          return true;
 300      },
 301  
 302      /**
 303       * Reorder each pagebreak by iterating through each related slot.
 304       *
 305       * @method reorderPageBreaks
 306       * @return void
 307       */
 308      reorderPageBreaks: function() {
 309          // Get list of slot nodes.
 310          var slots = this.getSlots();
 311          var slotnumber = 0;
 312          // Loop through slots incrementing the number each time.
 313          slots.each(function(slot, key) {
 314              slotnumber++;
 315              var pagebreak = this.getPageBreak(slot);
 316              var nextitem = slot.next('li.activity');
 317              if (!nextitem) {
 318                  // Last slot in a section. Should not have an icon.
 319                  return;
 320              }
 321  
 322              // No pagebreak and not last slot. Add one.
 323              if (!pagebreak) {
 324                  pagebreak = this.addPageBreak(slot);
 325              }
 326  
 327              // Remove last page break if there is one.
 328              if (pagebreak && key === slots.size() - 1) {
 329                  this.removePageBreak(slot);
 330              }
 331  
 332              // Get page break anchor element.
 333              var pagebreaklink = pagebreak.get('childNodes').item(0);
 334  
 335              // Get the correct title.
 336              var action = '';
 337              var iconname = '';
 338              if (Y.Moodle.mod_quiz.util.page.isPage(nextitem)) {
 339                  action = 'removepagebreak';
 340                  iconname = 'e/remove_page_break';
 341              } else {
 342                  action = 'addpagebreak';
 343                  iconname = 'e/insert_page_break';
 344              }
 345  
 346              // Update the link and image titles
 347              pagebreaklink.set('title', M.util.get_string(action, 'quiz'));
 348              pagebreaklink.setData('action', action);
 349              // Update the image title.
 350              var icon = pagebreaklink.one(this.SELECTORS.ICON);
 351              icon.set('title', M.util.get_string(action, 'quiz'));
 352              icon.set('alt', M.util.get_string(action, 'quiz'));
 353  
 354              // Update the image src.
 355              icon.set('src', M.util.image_url(iconname));
 356  
 357              // Get anchor url parameters as an associative array.
 358              var params = Y.QueryString.parse(pagebreaklink.get('href'));
 359              // Update slot number.
 360              params.slot = slotnumber;
 361              // Create the new url.
 362              var newurl = '';
 363              for (var index in params) {
 364                  if (newurl.length) {
 365                      newurl += "&";
 366                  }
 367                  newurl += index + "=" + params[index];
 368              }
 369              // Update the anchor.
 370              pagebreaklink.set('href', newurl);
 371          }, this);
 372      },
 373  
 374      /**
 375       * Update the dependency icons.
 376       *
 377       * @method updateAllDependencyIcons
 378       * @return void
 379       */
 380      updateAllDependencyIcons: function() {
 381          // Get list of slot nodes.
 382          var slots = this.getSlots(),
 383              slotnumber = 0,
 384              previousslot = null;
 385          // Loop through slots incrementing the number each time.
 386          slots.each(function(slot) {
 387              slotnumber++;
 388  
 389              if (slotnumber == 1 || previousslot.getData('canfinish') === '0') {
 390                  slot.one(this.SELECTORS.DEPENDENCY_WRAPPER).addClass(this.CSS.CANNOT_DEPEND);
 391              } else {
 392                  slot.one(this.SELECTORS.DEPENDENCY_WRAPPER).removeClass(this.CSS.CANNOT_DEPEND);
 393              }
 394              this.updateDependencyIcon(slot, null);
 395  
 396              previousslot = slot;
 397          }, this);
 398      },
 399  
 400      /**
 401       * Update the slot icon to indicate the new requiresprevious state.
 402       *
 403       * @method slot Slot node
 404       * @method requiresprevious Whether this node now requires the previous one.
 405       * @return void
 406       */
 407      updateDependencyIcon: function(slot, requiresprevious) {
 408          var link = slot.one(this.SELECTORS.DEPENDENCY_LINK);
 409          var icon = slot.one(this.SELECTORS.DEPENDENCY_ICON);
 410          var previousSlot = this.getPrevious(slot);
 411          var a = {thisq: this.getNumber(slot)};
 412          if (previousSlot) {
 413              a.previousq = this.getNumber(previousSlot);
 414          }
 415  
 416          if (requiresprevious === null) {
 417              requiresprevious = link.getData('action') === 'removedependency';
 418          }
 419  
 420          if (requiresprevious) {
 421              link.set('title', M.util.get_string('questiondependencyremove', 'quiz', a));
 422              link.setData('action', 'removedependency');
 423              icon.set('alt', M.util.get_string('questiondependsonprevious', 'quiz'));
 424              icon.set('src', M.util.image_url('t/locked', 'moodle'));
 425          } else {
 426              link.set('title', M.util.get_string('questiondependencyadd', 'quiz', a));
 427              link.setData('action', 'adddependency');
 428              icon.set('alt', M.util.get_string('questiondependencyfree', 'quiz'));
 429              icon.set('src', M.util.image_url('t/unlocked', 'moodle'));
 430          }
 431      }
 432  };
 433  
 434  
 435  }, '@VERSION@', {"requires": ["node", "moodle-mod_quiz-util-base"]});


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