[ Index ]

PHP Cross Reference of MediaWiki-1.24.0

title

Body

[close]

/extensions/WikiEditor/modules/ -> jquery.wikiEditor.toolbar.js (source)

   1  /**
   2   * Toolbar module for wikiEditor
   3   */
   4  /*jshint onevar:false */
   5  ( function ( mw, $ ) { $.wikiEditor.modules.toolbar = {
   6  
   7  /**
   8   * API accessible functions
   9   */
  10  api : {
  11      addToToolbar : function ( context, data ) {
  12  
  13          var smooth = true, type, i;
  14  
  15          for ( type in data ) {
  16              switch ( type ) {
  17                  case 'sections':
  18                      var    $sections = context.modules.toolbar.$toolbar.find( 'div.sections' ),
  19                          $tabs = context.modules.toolbar.$toolbar.find( 'div.tabs' );
  20                      for ( var section in data[type] ) {
  21                          if ( section === 'main' ) {
  22                              // Section
  23                              context.modules.toolbar.$toolbar.prepend(
  24                                  $.wikiEditor.modules.toolbar.fn.buildSection(
  25                                      context, section, data[type][section]
  26                                  )
  27                              );
  28                              continue;
  29                          }
  30                          // Section
  31                          $sections.append(
  32                              $.wikiEditor.modules.toolbar.fn.buildSection( context, section, data[type][section] )
  33                          );
  34                          // Tab
  35                          $tabs.append(
  36                              $.wikiEditor.modules.toolbar.fn.buildTab( context, section, data[type][section] )
  37                          );
  38                      }
  39                      break;
  40                  case 'groups':
  41                      if ( !( 'section' in data ) ) {
  42                          continue;
  43                      }
  44                      var    $section = context.modules.toolbar.$toolbar.find( 'div[rel="' + data.section + '"].section' );
  45                      for ( var group in data[type] ) {
  46                          // Group
  47                          $section.append(
  48                              $.wikiEditor.modules.toolbar.fn.buildGroup( context, group, data[type][group] )
  49                          );
  50                      }
  51                      smooth = false;
  52                      break;
  53                  case 'tools':
  54                      if ( !( 'section' in data && 'group' in data ) ) {
  55                          continue;
  56                      }
  57                      var $group = context.modules.toolbar.$toolbar.find(
  58                          'div[rel="' + data.section + '"].section ' + 'div[rel="' + data.group + '"].group'
  59                      );
  60                      for ( var tool in data[type] ) {
  61                          // Tool
  62                          $group.append( $.wikiEditor.modules.toolbar.fn.buildTool( context, tool, data[type][tool] ) );
  63                      }
  64                      if ( $group.children().length ) {
  65                          $group.removeClass( 'empty' );
  66                      }
  67                      smooth = false;
  68                      break;
  69                  case 'pages':
  70                      if ( !( 'section' in data ) ) {
  71                          continue;
  72                      }
  73                      var $pages = context.modules.toolbar.$toolbar.find(
  74                          'div[rel="' + data.section + '"].section .pages'
  75                      );
  76                      var $index = context.modules.toolbar.$toolbar.find(
  77                          'div[rel="' + data.section + '"].section .index'
  78                      );
  79                      for ( var page in data[type] ) {
  80                          // Page
  81                          $pages.append( $.wikiEditor.modules.toolbar.fn.buildPage( context, page, data[type][page] ) );
  82                          // Index
  83                          $index.append(
  84                              $.wikiEditor.modules.toolbar.fn.buildBookmark( context, page, data[type][page] )
  85                          );
  86                      }
  87                      $.wikiEditor.modules.toolbar.fn.updateBookletSelection( context, page, $pages, $index );
  88                      smooth = false;
  89                      break;
  90                  case 'rows':
  91                      if ( !( 'section' in data && 'page' in data ) ) {
  92                          continue;
  93                      }
  94                      var $table = context.modules.toolbar.$toolbar.find(
  95                          'div[rel="' + data.section + '"].section ' + 'div[rel="' + data.page + '"].page table'
  96                      );
  97                      for ( i = 0; i < data.rows.length; i++ ) {
  98                          // Row
  99                          $table.append( $.wikiEditor.modules.toolbar.fn.buildRow( context, data.rows[i] ) );
 100                      }
 101                      smooth = false;
 102                      break;
 103                  case 'characters':
 104                      if ( !( 'section' in data && 'page' in data ) ) {
 105                          continue;
 106                      }
 107                      var $characters = context.modules.toolbar.$toolbar.find(
 108                          'div[rel="' + data.section + '"].section ' + 'div[rel="' + data.page + '"].page div'
 109                      );
 110                      var actions = $characters.data( 'actions' );
 111                      for ( i = 0; i < data.characters.length; i++ ) {
 112                          // Character
 113                          $characters
 114                          .append(
 115                              $( $.wikiEditor.modules.toolbar.fn.buildCharacter( data.characters[i], actions ) )
 116                                  .mousedown( function ( e ) {
 117                                      context.fn.saveCursorAndScrollTop();
 118                                      // No dragging!
 119                                      e.preventDefault();
 120                                      return false;
 121                                  } )
 122                                  .click( function ( e ) {
 123                                      $.wikiEditor.modules.toolbar.fn.doAction( $( this ).parent().data( 'context' ),
 124                                          $( this ).parent().data( 'actions' )[$( this ).attr( 'rel' )] );
 125                                      e.preventDefault();
 126                                      return false;
 127                                  } )
 128                          );
 129                      }
 130                      smooth = false;
 131                      break;
 132                  default: break;
 133              }
 134          }
 135  
 136          // Fix div.section size after adding things; if smooth is true uses a smooth
 137          // animation, otherwise just change height (breaking any ongoing animation)
 138          var $divSections = context.modules.toolbar.$toolbar.find( 'div.sections' );
 139          var $visibleSection = $divSections.find( '.section-visible' );
 140          if ( $visibleSection.size() ) {
 141              if ( smooth ) {
 142                  $divSections.animate( { 'height': $visibleSection.outerHeight() }, 'fast' );
 143              } else {
 144                  $divSections.height( $visibleSection.outerHeight() );
 145              }
 146          }
 147      },
 148      removeFromToolbar : function ( context, data ) {
 149          if ( typeof data.section === 'string' ) {
 150              // Section
 151              var tab = 'div.tabs span[rel="' + data.section + '"].tab';
 152              var target = 'div[rel="' + data.section + '"].section';
 153              var group = null;
 154              if ( typeof data.group === 'string' ) {
 155                  // Toolbar group
 156                  target += ' div[rel="' + data.group + '"].group';
 157                  if ( typeof data.tool === 'string' ) {
 158                      // Save for later checking if empty
 159                      group = target;
 160                      // Tool
 161                      target = target + ' a[rel="' + data.tool + '"].tool, ' + target + ' img[rel="' + data.tool + '"].tool';
 162                  }
 163              } else if ( typeof data.page === 'string' ) {
 164                  // Booklet page
 165                  var index = target + ' div.index div[rel="' + data.page + '"]';
 166                  target += ' div.pages div[rel="' + data.page + '"].page';
 167                  if ( typeof data.character === 'string' ) {
 168                      // Character
 169                      target += ' span[rel="' + data.character + '"]';
 170                  } else if ( typeof data.row === 'number' ) {
 171                      // Table row
 172                      target += ' table tr:not(:has(th)):eq(' + data.row + ')';
 173                  } else {
 174                      // Just a page, remove the index too!
 175                      context.modules.toolbar.$toolbar.find( index ).remove();
 176                      $.wikiEditor.modules.toolbar.fn.updateBookletSelection(
 177                          context,
 178                          null,
 179                          context.modules.toolbar.$toolbar.find( target ),
 180                          context.modules.toolbar.$toolbar.find( index )
 181                      );
 182                  }
 183              } else {
 184                  // Just a section, remove the tab too!
 185                  context.modules.toolbar.$toolbar.find( tab ).remove();
 186              }
 187              context.modules.toolbar.$toolbar.find( target ).remove();
 188              // Hide empty groups
 189              if ( group ) {
 190                  var $group = context.modules.toolbar.$toolbar.find( group );
 191                  if ( $group.children().length === 0 ) {
 192                      $group.addClass( 'empty' );
 193                  }
 194              }
 195          }
 196      }
 197  },
 198  /**
 199   * Event handlers
 200   */
 201  evt: {
 202      /**
 203       * @param context
 204       * @param event
 205       */
 206      resize: function ( context ) {
 207          context.$ui.find( '.sections' ).height( context.$ui.find( '.sections .section-visible' ).outerHeight() );
 208      }
 209  },
 210  /**
 211   * Internally used functions
 212   */
 213  fn: {
 214      /**
 215       * Creates a toolbar module within a wikiEditor
 216       *
 217       * @param {Object} context Context object of editor to create module in
 218       * @param {Object} config Configuration object to create module from
 219       */
 220      create : function ( context, config ) {
 221          if ( '$toolbar' in context.modules.toolbar ) {
 222              return;
 223          }
 224          context.modules.toolbar.$toolbar = $( '<div>' )
 225              .addClass( 'wikiEditor-ui-toolbar' )
 226              .attr( 'id', 'wikiEditor-ui-toolbar' );
 227          $.wikiEditor.modules.toolbar.fn.build( context, config );
 228          context.$ui.find( '.wikiEditor-ui-top' ).append( context.modules.toolbar.$toolbar );
 229      },
 230      /**
 231       * Performs an operation based on parameters
 232       *
 233       * @param {Object} context
 234       * @param {Object} action
 235       * @param {Object} source
 236       */
 237      doAction : function ( context, action ) {
 238          switch ( action.type ) {
 239              case 'replace':
 240              case 'encapsulate':
 241                  var parts = {
 242                      'pre' : $.wikiEditor.autoMsg( action.options, 'pre' ),
 243                      'peri' : $.wikiEditor.autoMsg( action.options, 'peri' ),
 244                      'post' : $.wikiEditor.autoMsg( action.options, 'post' )
 245                  };
 246                  var replace = action.type === 'replace';
 247                  if ( 'regex' in action.options && 'regexReplace' in action.options ) {
 248                      var selection = context.$textarea.textSelection( 'getSelection' );
 249                      if ( selection !== '' && selection.match( action.options.regex ) ) {
 250                          parts.peri = selection.replace( action.options.regex,
 251                              action.options.regexReplace );
 252                          parts.pre = parts.post = '';
 253                          replace = true;
 254                      }
 255                  }
 256                  context.$textarea.textSelection(
 257                      'encapsulateSelection',
 258                      $.extend( {}, action.options, parts, { 'replace': replace } )
 259                  );
 260                  break;
 261              case 'callback':
 262                  if ( typeof action.execute === 'function' ) {
 263                      action.execute( context );
 264                  }
 265                  break;
 266              case 'dialog':
 267                  context.fn.saveSelection();
 268                  context.$textarea.wikiEditor( 'openDialog', action.module );
 269                  break;
 270              default: break;
 271          }
 272      },
 273      buildGroup : function ( context, id, group ) {
 274          var $group = $( '<div>' ).attr( { 'class' : 'group group-' + id, 'rel' : id } );
 275          var label = $.wikiEditor.autoMsg( group, 'label' );
 276          if ( label ) {
 277              var $label = $( '<span />' )
 278                  .addClass( 'label' )
 279                  .html( label );
 280              $group.append( $label );
 281          }
 282          var empty = true;
 283          if ( 'tools' in group ) {
 284              for ( var tool in group.tools ) {
 285                  tool = $.wikiEditor.modules.toolbar.fn.buildTool( context, tool, group.tools[tool] );
 286                  if ( tool ) {
 287                      // Consider a group with only hidden tools empty as well
 288                      // .is( ':visible' ) always returns false because tool is not attached to the DOM yet
 289                      empty = empty && tool.css( 'display' ) === 'none';
 290                      $group.append( tool );
 291                  }
 292              }
 293          }
 294          if ( empty ) {
 295              $group.addClass( 'empty' );
 296          }
 297          return $group;
 298      },
 299      buildTool : function ( context, id, tool ) {
 300          if ( 'filters' in tool ) {
 301              for ( var i = 0; i < tool.filters.length; i++ ) {
 302                  if ( $( tool.filters[i] ).size() === 0 ) {
 303                      return null;
 304                  }
 305              }
 306          }
 307          var label = $.wikiEditor.autoMsg( tool, 'label' );
 308          switch ( tool.type ) {
 309              case 'button':
 310                  var src = $.wikiEditor.autoIcon( tool.icon, $.wikiEditor.imgPath + 'toolbar/' );
 311                  var $button = null;
 312                  if ( 'offset' in tool ) {
 313                      var offsetOrIcon = $.wikiEditor.autoIconOrOffset( tool.icon, tool.offset,
 314                          $.wikiEditor.imgPath + 'toolbar/'
 315                      );
 316                      if ( typeof offsetOrIcon === 'object' ) {
 317                          $button = $( '<a>' )
 318                              .attr( {
 319                                  'href' : '#',
 320                                  'title' : label,
 321                                  'rel' : id,
 322                                  'role' : 'button',
 323                                  'class' : 'tool tool-button wikiEditor-toolbar-spritedButton'
 324                              } )
 325                              .text( label )
 326                              .css( 'backgroundPosition', offsetOrIcon[0] + 'px ' + offsetOrIcon[1] + 'px' );
 327                      }
 328                  }
 329                  if ( !$button ) {
 330                      $button = $( '<img>' )
 331                          .attr( {
 332                              'src' : src,
 333                              'width' : 22,
 334                              'height' : 22,
 335                              'alt' : label,
 336                              'title' : label,
 337                              'rel' : id,
 338                              'role' : 'button',
 339                              'class' : 'tool tool-button'
 340                          } );
 341                  }
 342                  if ( 'action' in tool ) {
 343                      $button
 344                          .data( 'action', tool.action )
 345                          .data( 'context', context )
 346                          .mousedown( function ( e ) {
 347                              context.fn.saveCursorAndScrollTop();
 348                              // No dragging!
 349                              e.preventDefault();
 350                              return false;
 351                          } )
 352                          .click( function ( e ) {
 353                              $.wikiEditor.modules.toolbar.fn.doAction(
 354                                  $( this ).data( 'context' ), $( this ).data( 'action' ), $( this )
 355                              );
 356                              e.preventDefault();
 357                              return false;
 358                          } );
 359                  }
 360                  return $button;
 361              case 'select':
 362                  var $select = $( '<div>' )
 363                      .attr( { 'rel' : id, 'class' : 'tool tool-select' } );
 364                  var $options = $( '<div>' ).addClass( 'options' );
 365                  if ( 'list' in tool ) {
 366                      for ( var option in tool.list ) {
 367                          var optionLabel = $.wikiEditor.autoMsg( tool.list[option], 'label' );
 368                          $options.append(
 369                              $( '<a>' )
 370                                  .data( 'action', tool.list[option].action )
 371                                  .data( 'context', context )
 372                                  .mousedown( function ( e ) {
 373                                      context.fn.saveCursorAndScrollTop();
 374                                      // No dragging!
 375                                      e.preventDefault();
 376                                      return false;
 377                                  } )
 378                                  .click( function ( e ) {
 379                                      $.wikiEditor.modules.toolbar.fn.doAction(
 380                                          $( this ).data( 'context' ), $( this ).data( 'action' ), $( this )
 381                                      );
 382                                      // Hide the dropdown
 383                                      // Sanity check: if this somehow gets called while the dropdown
 384                                      // is hidden, don't show it
 385                                      if ( $( this ).parent().is( ':visible' ) ) {
 386                                          $( this ).parent().animate( { 'opacity': 'toggle' }, 'fast' );
 387                                      }
 388                                      e.preventDefault();
 389                                      return false;
 390                                  } )
 391                                  .text( optionLabel )
 392                                  .addClass( 'option' )
 393                                  .attr( { 'rel': option, 'href': '#' } )
 394                          );
 395                      }
 396                  }
 397                  $select.append( $( '<div>' ).addClass( 'menu' ).append( $options ) );
 398                  $select.append( $( '<a>' )
 399                          .addClass( 'label' )
 400                          .text( label )
 401                          .data( 'options', $options )
 402                          .attr( 'href', '#' )
 403                          .mousedown( function ( e ) {
 404                              // No dragging!
 405                              e.preventDefault();
 406                              return false;
 407                          } )
 408                          .click( function ( e ) {
 409                              $( this ).data( 'options' ).animate( { 'opacity': 'toggle' }, 'fast' );
 410                              e.preventDefault();
 411                              return false;
 412                          } )
 413                  );
 414                  return $select;
 415              default:
 416                  return null;
 417          }
 418      },
 419      buildBookmark : function ( context, id, page ) {
 420          var label = $.wikiEditor.autoMsg( page, 'label' );
 421          return $( '<div>' )
 422              .text( label )
 423              .attr( 'rel', id )
 424              .data( 'context', context )
 425              .mousedown( function ( e ) {
 426                  context.fn.saveCursorAndScrollTop();
 427                  // No dragging!
 428                  e.preventDefault();
 429                  return false;
 430              } )
 431              .click( function ( event ) {
 432                  $( this ).parent().parent().find( '.page' ).hide();
 433                  $( this ).parent().parent().find( '.page-' + $( this ).attr( 'rel' ) ).show();
 434                  $( this ).siblings().removeClass( 'current' );
 435                  $( this ).addClass( 'current' );
 436                  var section = $( this ).parent().parent().attr( 'rel' );
 437                  $.cookie(
 438                      'wikiEditor-' + $( this ).data( 'context' ).instance + '-booklet-' + section + '-page',
 439                      $( this ).attr( 'rel' ),
 440                      { expires: 30, path: '/' }
 441                  );
 442                  context.fn.restoreCursorAndScrollTop();
 443                  // No dragging!
 444                  event.preventDefault();
 445                  return false;
 446              } );
 447      },
 448      buildPage : function ( context, id, page ) {
 449          var html, i;
 450          var $page = $( '<div>' ).attr( {
 451              'class' : 'page page-' + id,
 452              'rel' : id
 453          } );
 454          switch ( page.layout ) {
 455              case 'table':
 456                  $page.addClass( 'page-table' );
 457                  html =
 458                      '<table cellpadding=0 cellspacing=0 ' + 'border=0 width="100%" class="table table-' + id + '">';
 459                  if ( 'headings' in page ) {
 460                      html += $.wikiEditor.modules.toolbar.fn.buildHeading( context, page.headings );
 461                  }
 462                  if ( 'rows' in page ) {
 463                      for ( i = 0; i < page.rows.length; i++ ) {
 464                          html += $.wikiEditor.modules.toolbar.fn.buildRow( context, page.rows[i] );
 465                      }
 466                  }
 467                  $page.html( html + '</table>' );
 468                  break;
 469              case 'characters':
 470                  $page.addClass( 'page-characters' );
 471                  var $characters = $( '<div>' ).data( 'context', context ).data( 'actions', {} );
 472                  var actions = $characters.data( 'actions' );
 473                  if ( 'language' in page ) {
 474                      $characters.attr( 'lang', page.language );
 475                  }
 476                  if ( 'direction' in page ) {
 477                      $characters.attr( 'dir', page.direction );
 478                  } else {
 479                      // By default it should be explicit ltr for all scripts.
 480                      // Without this some conjoined ltr characters look
 481                      // weird in rtl wikis.
 482                      $characters.attr( 'dir', 'ltr' );
 483                  }
 484                  if ( 'characters' in page ) {
 485                      html = '';
 486                      for ( i = 0; i < page.characters.length; i++ ) {
 487                          html += $.wikiEditor.modules.toolbar.fn.buildCharacter( page.characters[i], actions );
 488                      }
 489                      $characters
 490                          .html( html )
 491                          .children()
 492                          .mousedown( function ( e ) {
 493                              context.fn.saveCursorAndScrollTop();
 494                              // No dragging!
 495                              e.preventDefault();
 496                              return false;
 497                          } )
 498                          .click( function ( e ) {
 499                              $.wikiEditor.modules.toolbar.fn.doAction(
 500                                  $( this ).parent().data( 'context' ),
 501                                  $( this ).parent().data( 'actions' )[$( this ).attr( 'rel' )],
 502                                  $( this )
 503                              );
 504                              e.preventDefault();
 505                              return false;
 506                          } );
 507                  }
 508                  $page.append( $characters );
 509                  break;
 510          }
 511          return $page;
 512      },
 513      buildHeading : function ( context, headings ) {
 514          var html = '<tr>';
 515          for ( var i = 0; i< headings.length; i++ ) {
 516              html += '<th>' + $.wikiEditor.autoMsg( headings[i], ['html', 'text'] ) + '</th>';
 517          }
 518          return html + '</tr>';
 519      },
 520      buildRow : function ( context, row ) {
 521          var html = '<tr>';
 522          for ( var cell in row ) {
 523              html += '<td class="cell cell-' + cell + '"><span>' +
 524                  $.wikiEditor.autoMsg( row[cell], ['html', 'text'] ) + '</span></td>';
 525          }
 526          return html + '</tr>';
 527      },
 528      buildCharacter : function ( character, actions ) {
 529          if ( typeof character === 'string' ) {
 530              character = {
 531                  'label' : character,
 532                  'action' : {
 533                      'type' : 'replace',
 534                      'options' : {
 535                          'peri' : character,
 536                          'selectPeri': false
 537                      }
 538                  }
 539              };
 540          // In some cases the label for the character isn't the same as the
 541          // character that gets inserted (e.g. Hebrew vowels)
 542          } else if ( character && 0 in character && 1 in character ) {
 543              character = {
 544                  'label' : character[0],
 545                  'action' : {
 546                      'type' : 'replace',
 547                      'options' : {
 548                          'peri' : character[1],
 549                          'selectPeri': false
 550                      }
 551                  }
 552              };
 553          }
 554          if ( character && 'action' in character && 'label' in character ) {
 555              actions[character.label] = character.action;
 556              if ( character.titleMsg !== undefined ) {
 557                  return mw.html.element(
 558                      'span',
 559                      { 'rel': character.label, 'title': mw.msg( character.titleMsg ) },
 560                      character.label
 561                  );
 562              } else {
 563                  return mw.html.element( 'span', { 'rel': character.label }, character.label );
 564              }
 565          }
 566          mw.log( 'A character for the toolbar was undefined. This is not supposed to happen. Double check the config.' );
 567          // bug 31673; also an additional fix for bug 24208...
 568          return '';
 569      },
 570      buildTab : function ( context, id, section ) {
 571          var selected = $.cookie( 'wikiEditor-' + context.instance + '-toolbar-section' );
 572          // Re-save cookie
 573          if ( selected !== null ) {
 574              $.cookie( 'wikiEditor-' + context.instance + '-toolbar-section', selected, { expires: 30, path: '/' } );
 575          }
 576          var $link =
 577              $( '<a>' )
 578                  .addClass( selected === id ? 'current' : null )
 579                  .attr( {
 580                      href: '#',
 581                      role: 'button',
 582                      'aria-pressed': 'false',
 583                      'aria-controls': 'wikiEditor-section-' + id
 584                  } )
 585                  .text( $.wikiEditor.autoMsg( section, 'label' ) )
 586                  .data( 'context', context )
 587                  .mouseup( function () {
 588                      $( this ).blur();
 589                  } )
 590                  .mousedown( function ( e ) {
 591                      // No dragging!
 592                      e.preventDefault();
 593                      return false;
 594                  } )
 595                  .click( function ( e ) {
 596                      // We have to set aria-pressed over here, as NVDA wont recognize it
 597                      // if we do it in the below .each as it seems
 598                      $( this ).attr( 'aria-pressed', 'true' );
 599                      $( '.tab > a' ).each( function ( i, elem ) {
 600                          if ( elem !== e.target ) {
 601                              $( elem ).attr( 'aria-pressed', 'false' );
 602                          }
 603                      } );
 604                      var $sections = $( this ).data( 'context' ).$ui.find( '.sections' );
 605                      var $section =
 606                          $( this ).data( 'context' ).$ui.find( '.section-' + $( this ).parent().attr( 'rel' ) );
 607                      var show = !$section.hasClass( 'section-visible' );
 608                      $section.parent().find( '.section-visible' )
 609                          .css( 'position', 'absolute' )
 610                          .attr( 'aria-expanded', 'false' )
 611                          .removeClass( 'section-visible' )
 612                          .animate( { opacity: 0 }, 'fast', 'linear', function () {
 613                              $( this ).addClass( 'section-hidden' ).css( 'position', 'static' );
 614                          } );
 615  
 616                      $( this ).parent().parent().find( 'a' ).removeClass( 'current' );
 617                      $sections.css( 'overflow', 'hidden' );
 618                      var animate = function ( $that ) {
 619                          $sections
 620                          .animate( { 'height': $section.outerHeight() }, $section.outerHeight() * 2, function () {
 621                              $that.css( 'overflow', 'visible' ).css( 'height', 'auto' );
 622                              context.fn.trigger( 'resize' );
 623                          } );
 624                      };
 625                      if ( show ) {
 626                          $section.removeClass( 'section-hidden' )
 627                              .attr( 'aria-expanded', 'true' )
 628                              .animate( {opacity: 100.0}, 'fast', 'linear', function () {
 629                                  $(this).addClass( 'section-visible' );
 630                              } );
 631  
 632                          if ( $section.hasClass( 'loading' ) ) {
 633                              // Loading of this section was deferred, load it now
 634                              var $that = $( this );
 635                              $that.addClass( 'current loading' );
 636                              setTimeout( function () {
 637                                  $section.trigger( 'loadSection' );
 638                                  animate( $that );
 639                                  $that.removeClass( 'loading' );
 640                              }, 1000 );
 641                          } else {
 642                              animate( $( this ) );
 643                              $( this ).addClass( 'current' );
 644                          }
 645                      } else {
 646                          $sections
 647                              .css( 'height', $section.outerHeight() )
 648                              .animate( { 'height': 0 }, $section.outerHeight() * 2, function () {
 649                                  $( this ).css( { 'overflow': 'visible' } );
 650                                  context.fn.trigger( 'resize' );
 651                              } );
 652                      }
 653                      // Save the currently visible section
 654                      $.cookie(
 655                          'wikiEditor-' + $( this ).data( 'context' ).instance + '-toolbar-section',
 656                          show ? $section.attr( 'rel' ) : null,
 657                          { expires: 30, path: '/' }
 658                      );
 659                      e.preventDefault();
 660                      return false;
 661                  } );
 662          return $( '<span>' )
 663              .attr( {
 664                  'class' : 'tab tab-' + id,
 665                  'rel' : id
 666              } )
 667              .append( $link );
 668      },
 669      buildSection: function ( context, id, section ) {
 670          var $section = $( '<div>' ).attr( {
 671              'class': section.type + ' section section-' + id,
 672              'rel': id,
 673              id: 'wikiEditor-section-' + id
 674          } );
 675          var selected = $.cookie( 'wikiEditor-' + context.instance + '-toolbar-section' );
 676          var show = selected === id;
 677  
 678          if ( section.deferLoad !== undefined && section.deferLoad && id !== 'main' && !show ) {
 679              // This class shows the spinner and serves as a marker for the click handler in buildTab()
 680              $section.addClass( 'loading' ).append( $( '<div>' ).addClass( 'spinner' ) );
 681              $section.bind( 'loadSection', function () {
 682                  $.wikiEditor.modules.toolbar.fn.reallyBuildSection( context, id, section, $section );
 683                  $section.removeClass( 'loading' );
 684              } );
 685          } else {
 686              $.wikiEditor.modules.toolbar.fn.reallyBuildSection( context, id, section, $section );
 687          }
 688  
 689          // Show or hide section
 690          if ( id !== 'main' ) {
 691              $section.attr( 'aria-expanded', show ? 'true' : 'false' );
 692  
 693              if ( show ) {
 694                  $section.addClass( 'section-visible' );
 695              } else {
 696                  $section.addClass( 'section-hidden' );
 697              }
 698          }
 699          return $section;
 700      },
 701      reallyBuildSection: function ( context, id, section, $section ) {
 702          context.$textarea.trigger( 'wikiEditor-toolbar-buildSection-' + $section.attr( 'rel' ), [section] );
 703          switch ( section.type ) {
 704              case 'toolbar':
 705                  if ( 'groups' in section ) {
 706                      for ( var group in section.groups ) {
 707                          $section.append(
 708                              $.wikiEditor.modules.toolbar.fn.buildGroup( context, group, section.groups[group] )
 709                          );
 710                      }
 711                  }
 712                  break;
 713              case 'booklet':
 714                  var $pages = $( '<div>' ).addClass( 'pages' );
 715                  var $index = $( '<div>' ).addClass( 'index' );
 716                  if ( 'pages' in section ) {
 717                      for ( var page in section.pages ) {
 718                          $pages.append(
 719                              $.wikiEditor.modules.toolbar.fn.buildPage( context, page, section.pages[page] )
 720                          );
 721                          $index.append(
 722                              $.wikiEditor.modules.toolbar.fn.buildBookmark( context, page, section.pages[page] )
 723                          );
 724                      }
 725                  }
 726                  $section.append( $index ).append( $pages );
 727                  $.wikiEditor.modules.toolbar.fn.updateBookletSelection( context, id, $pages, $index );
 728                  break;
 729          }
 730      },
 731      updateBookletSelection : function ( context, id, $pages, $index ) {
 732          /*jshint eqnull:true */
 733          var cookie = 'wikiEditor-' + context.instance + '-booklet-' + id + '-page';
 734          var selected = $.cookie( cookie );
 735          // Re-save cookie
 736          if ( selected != null ) {
 737              $.cookie( cookie, selected, { expires: 30, path: '/' } );
 738          }
 739          var $selectedIndex = $index.find( '*[rel="' + selected + '"]' );
 740          if ( $selectedIndex.size() === 0 ) {
 741              $selectedIndex = $index.children().eq( 0 );
 742              selected = $selectedIndex.attr( 'rel' );
 743              $.cookie( cookie, selected, { expires: 30, path: '/' } );
 744          }
 745          $pages.children().hide();
 746          $pages.find( '*[rel="' + selected + '"]' ).show();
 747          $index.children().removeClass( 'current' );
 748          $selectedIndex.addClass( 'current' );
 749      },
 750      build : function ( context, config ) {
 751          var $tabs = $( '<div>' ).addClass( 'tabs' ).appendTo( context.modules.toolbar.$toolbar );
 752          var $sections = $( '<div>' ).addClass( 'sections' ).appendTo( context.modules.toolbar.$toolbar );
 753          context.modules.toolbar.$toolbar.append( $( '<div>' ).css( 'clear', 'both' ) );
 754          var sectionQueue = [];
 755          for ( var section in config ) {
 756              if ( section === 'main' ) {
 757                  context.modules.toolbar.$toolbar.prepend(
 758                      $.wikiEditor.modules.toolbar.fn.buildSection( context, section, config[section] )
 759                  );
 760              } else {
 761                  sectionQueue.push( {
 762                      '$sections' : $sections,
 763                      'context' : context,
 764                      'id' : section,
 765                      'config' : config[section]
 766                  } );
 767                  $tabs.append( $.wikiEditor.modules.toolbar.fn.buildTab( context, section, config[section] ) );
 768              }
 769          }
 770          $.eachAsync( sectionQueue, {
 771              'bulk' : 0,
 772              'end' : function () {
 773                  // HACK: Opera doesn't seem to want to redraw after these bits
 774                  // are added to the DOM, so we can just FORCE it!
 775                  var oldValue = $( 'body' ).css( 'position' );
 776                  $( 'body' ).css( 'position', 'static' );
 777                  $( 'body' ).css( 'position', oldValue );
 778  
 779                  context.$textarea.trigger( 'wikiEditor-toolbar-doneInitialSections' );
 780              },
 781              'loop' : function ( i, s ) {
 782                  s.$sections.append( $.wikiEditor.modules.toolbar.fn.buildSection( s.context, s.id, s.config ) );
 783                  var $section = s.$sections.find( '.section-visible' );
 784                  if ( $section.size() ) {
 785                      $sections.animate( { 'height': $section.outerHeight() }, $section.outerHeight() * 2, function ( ) {
 786                          context.fn.trigger( 'resize' );
 787                      } );
 788                  }
 789              }
 790          } );
 791      }
 792  }
 793  
 794  }; } )( mediaWiki, jQuery );


Generated: Fri Nov 28 14:03:12 2014 Cross-referenced by PHPXref 0.7.1